<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Two Player Games
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora159.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora161.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Two Player Games</H2>
<A NAME="sec-jeux"></A>The application presented in this section pursues two objectives. On
the one hand, it seeks to resolve problems related to the complexity
in searching state spaces, as well as showing that Objective CAML provides
useful tools for dealing with symbolic applications. On the other hand,
it also explores the benefits of using parametric modules to define a
generic scheme for constructing two player games, providing the ability
to factor out one part of the search, and making it easy to customize
components such as functions for evaluating or displaying a game
position.<BR>
<BR>
We first present the problem of games involving two players, then
describe the <EM>minimax-</EM><EM><FONT FACE=symbol>a</FONT><FONT FACE=symbol>b</FONT></EM> algorithm which provides an
efficient search of the tree of possible moves. We present a
parametric model for two player games. Then, we apply these functors
to implement two games: ``Connect Four'' (a vertical tic-tac-toe),
and Stonehenge (a game that involves constructing ley-lines).<BR>
<BR>
<A NAME="toc229"></A>
<H3> The Problem of Two Player Games</H3>Games involving two players represent one of the classic applications
of symbolic programming and provide a good example of problem solving
for at least two reasons:<BR>
<BR>
<UL>
<LI> The large number of solutions to be analyzed to obtain the best
possible move necessitates using methods other than brute force.<BR>
<BR>
For instance, in the game of chess, the number of possible moves
typically is around 30, and a game often involves around 40 moves per
player. This would require a search tree of around 30<SUP><FONT SIZE=2>80</FONT></SUP>
positions just to explore the complete tree for one player.<BR>
<BR>

<LI> The quality of a solution is easily verifiable. In particular,
it is possible to test the quality of a proposed solution from one program
by comparing it to that of another.</UL>First, assume that we are able to explore the total list of all
possible moves, given, as a starting point, a specific legal game
position. Such a program will require a function to generate legal
moves based on a starting position, as well as a function to evaluate
some ``score'' for each resulting position. The evaluation function
must give a maximum score to a winning position, and a minimal score
to a losing position. After picking an initial position, one may then
construct a tree of all possible variations, where each node
corresponds to a position, the adjacent siblings are obtained by
having played a move and with leaves having positions indicating
winning, losing, or null results. Once the tree is constructed,
its exploration permits determining if there exists a route leading
to victory, or a null position, failing that. The shortest path may
then be chosen to attain the desired goal.<BR>
<BR>
As the overall size of such a tree is generally too large for it to
be fully represented, it is typically necessary to limit what portions
of the tree are constructed. A first strategy is to limit the
``depth'' of the search, that is, the number of moves and responses
that are to be evaluated. One thus reduces the breadth of the tree as
well as its height. In such cases, leaf nodes will seldom be found
until nearly the end of the game.<BR>
<BR>
On the other hand, we may try to limit the number of moves selected
for additional evaluation. For this, we try to avoid evaluating any
but the most favorable moves, and start by examining the moves that
appear to be the very best. This immediately eliminates entire branches
of the tree. This leads to the <EM>minimax</EM> <FONT FACE=symbol>a</FONT> <FONT FACE=symbol>b</FONT> algorithm
presented in the next subsection.<BR>
<BR>
<A NAME="toc230"></A>
<H3> Minimax <FONT FACE=symbol>a</FONT><FONT FACE=symbol>b</FONT></H3>We present the <EM>minimax</EM> search and describe a variant optimized
using <FONT FACE=symbol>a</FONT> <FONT FACE=symbol>b</FONT> cuts. The implementation of this algorithm uses a
parametric module, <TT>FAlphabeta</TT> along with a representation of
the game and its evaluation function. We distinguish between the two
players by naming them A and B.<BR>
<BR>

<H4> Minimax</H4>The <EM>minimax</EM> algorithm is a depth-first search algorithm 
with a limit on the depth to which search is done. It requires:<BR>
<BR>
<UL>
<LI>
 a function to generate legal moves based on a position, and

<LI> a function to evaluate a game position.
</UL>Starting with some initial game position, the algorithm explores the
tree of all legal moves down to the requested depth. Scores associated
with leaves of the tree are calculated using an evaluation function.
A positive score indicates a good position for player A, while a
negative score indicates a poor position for player A, and thus a good
position for player B. For each player, the transition from
one position to another is either maximized (for player A) or
minimized (for player B). Each player tries to select his moves
in a manner that will be most profitable for him. In searching
for the best play for player A, a search of depth 1 tries to determine
the immediate move that maximizes the score of the new position.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora066.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.1: Maximizing search at a given location.</DIV><BR>

<A NAME="fig-max"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>In figure <A HREF="book-ora160.html#fig-max">17.1</A>, player A starts at position O, finds four
legal moves, constructs these new configurations, and evaluates them.
Based on these scores, the best position is P2, with a score of 8. This
value is propagated to position O, indicating that this position
provides a move to a new position, giving a score of 8 when the
player moves to C2. The search of depth 1 is, as a general rule,
insufficient, as it does not consider the possible
response of an adversary. Such a shallow search results in programs
that search greedily for immediate material gains (such as the prize
of a queen, in chess) without perceiving that the pieces are protected
or that the position is otherwise a losing one (such as a gambit of
trading one's queen for a mate). A deeper exploration to depth 2
permits perceiving at least the simplest such countermoves.<BR>
<BR>
Figure <A HREF="book-ora160.html#fig-maxmin">17.2</A> displays a supplementary analysis of the tree
that takes into consideration the possible responses of player B.
This search considers B's best moves. For this, the <EM>minimax</EM>
algorithm minimizes scores of depth 2.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora067.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.2: Maximizing and minimizing in depth-2 search.</DIV><BR>

<A NAME="fig-maxmin"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>Move P2, which provided an immediate position score of 8, leads to a 
position with a score of -3. In effect, if B plays D5, then the
score of Q5 will be -3. Based on this deeper examination, the move C1
limits the losses with a score of -1, and is thus the preferred move.<BR>
<BR>
In most games, it is possible to try to confuse the adversary, making
him play forced moves, trying to muddle the situation in the hope
that he will make a mistake. A shallow search of depth 2
would be completely inadequate for this sort of tactic. These sorts
of strategies are rarely able to be well exploited by a program
because it has no particular vision as to the likely evolution of the
positions towards the end of the game.<BR>
<BR>
The difficulty of increased depth of search comes in the form of a
combinatorial ``explosion.'' For example, with chess, the exploration
of two additional levels adds a factor of around a thousand times more
combinations (30 � 30). Thus, if one searches to a depth of 10,
one obtains around 5<SUP><FONT SIZE=2>14</FONT></SUP> positions, which represents too much to
search. For this reason, you must try to somehow trim the search tree.<BR>
<BR>
One may note in figure <A HREF="book-ora160.html#fig-maxmin">17.2</A> that it may be useless
to search the branch P3 insofar as the score of this
position at depth 1 is poorer than that found in branch P1. In
addition the branch P4 does not need to be completely explored. Based
on the calculation of Q7, one obtains a score inferior to that of P1,
which has already been completely explored. The calculations for Q8
and Q9 cannot improve this situation even if their scores are
better than Q7. In a minimizing mode, the poorest score is dropped.
The player knows then that these branches provide no useful new
options. The minimax variant <FONT FACE=symbol>a</FONT> <FONT FACE=symbol>b</FONT> uses this approach to
decrease the number of branches that must be explored.<BR>
<BR>

<H4> Minimax-<FONT FACE=symbol>a</FONT><FONT FACE=symbol>b</FONT></H4>We call the <FONT FACE=symbol>a</FONT> cut the <EM>lower limit</EM> of a maximizing node,
and cut <FONT FACE=symbol>b</FONT> the <EM>upper limit</EM> of a minimizing node. Figure
<A HREF="book-ora160.html#fig-maxminAB">17.3</A> shows the cuts carried out in branches P3 and P4
based on knowing the lower limit -1 of P1.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora068.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.3: Limit <FONT FACE=symbol>a</FONT> to one level max-min.</DIV><BR>

<A NAME="fig-maxminAB"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>As soon as the tree gets broader or deeper the number of cuts
increases, thus indicating large subtrees.<BR>
<BR>

<H4> A Parametric Module for <FONT FACE=symbol>a</FONT> <FONT FACE=symbol>b</FONT> Minimax </H4>
<A NAME="mod-falphabeta"></A>We want to produce a parametric module, <TT>FAlphabeta</TT>,
implementing this algorithm, which will be generically reusable for
all sorts of two player games. The parameters correspond, on the one
hand, to all the information about the proceedings of moves in the
game, and on the other hand, to the evaluation function.<BR>
<BR>

<H5> Interfaces.</H5>We declare two signatures: <TT>REPRESENTATION</TT> to represent plays; and
<TT>EVAL</TT> to evaluate a position.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>REPRESENTATION<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><B>sig</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>game_start<CODE> </CODE><CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>legal_moves<CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>move<CODE> </CODE>list<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>play<CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>move<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE><BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type REPRESENTATION =</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game</CODE><BR><CODE>    and move</CODE><BR><CODE>    val game_start : unit -&gt; game</CODE><BR><CODE>    val legal_moves : bool -&gt; game -&gt; move list</CODE><BR><CODE>    val play : bool -&gt; move -&gt; game -&gt; game</CODE><BR><CODE>  end</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR># <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>EVAL<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><B>sig</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>evaluate<CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>moreI<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>lessI<CODE>:</CODE><CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>is_leaf<CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>bool<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>is_stable<CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>bool<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>state<CODE> </CODE><CODE>=</CODE><CODE> </CODE>G<CODE> </CODE><CODE>|</CODE><CODE> </CODE>P<CODE> </CODE><CODE>|</CODE><CODE> </CODE>N<CODE> </CODE><CODE>|</CODE><CODE> </CODE>C<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>state_of<CODE> </CODE><CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>state<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type EVAL =</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game</CODE><BR><CODE>    val evaluate : bool -&gt; game -&gt; int</CODE><BR><CODE>    val moreI : int</CODE><BR><CODE>    val lessI : int</CODE><BR><CODE>    val is_leaf : bool -&gt; game -&gt; bool</CODE><BR><CODE>    val is_stable : bool -&gt; game -&gt; bool</CODE><BR><CODE>    type state = | G | P | N | C</CODE><BR><CODE>    val state_of : bool -&gt; game -&gt; state</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
Types <TT>game</TT> and <TT>move</TT> represent abstract types. A player is
represented by a boolean value. The function <TT>legal_moves</TT>
takes a player and position, and returns the list of possible moves.
The function <TT>play</TT> takes a player, a move, and a position, and
returns a new position. The values <TT>moreI</TT> and <TT>lessI</TT>
are the limits of the values returned by function
<TT>evaluate</TT>. The predicate <TT>is_leaf</TT> verifies if a
player in a given position can play. The predicate <TT>is_stable</TT>
indicates whether the position for the player represents a stable
position. The results of these functions influence the pursuit of the
exploration of moves when one attains the specified depth.
<BR>
<BR>
The signature <TT>ALPHABETA</TT> corresponds to the signature
resulting from the complete application of the parametric module that
one wishes to use. These hide the different auxiliary functions that
we use to implement the algorithm.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>ALPHABETA<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>sig</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>alphabeta<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>move<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type ALPHABETA =</CODE><BR><CODE>  sig type game and move val alphabeta : int -&gt; bool -&gt; game -&gt; move end</CODE><BR>

</PRE>
<BR>
<BR>
The function <TT>alphabeta</TT> takes as parameters the depth of the
search, the player, and the game position, returning the next move.<BR>
<BR>
We then define the functional signature <TT>FALPHABETA</TT> which must
correspond to that of the implementation of the functor.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>FALPHABETA<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>functor</B><CODE> </CODE><TT>(</TT>Rep<CODE> </CODE><CODE>:</CODE><CODE> </CODE>REPRESENTATION<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>functor</B><CODE> </CODE><TT>(</TT>Eval<CODE> </CODE><CODE>:</CODE><CODE> </CODE>EVAL<CODE> </CODE><B>with</B><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>ALPHABETA<CODE> </CODE><B>with</B><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.move<CODE> </CODE>;;<BR><CODE>module type FALPHABETA =</CODE><BR><CODE>  functor(Rep : REPRESENTATION) -&gt;</CODE><BR><CODE>    functor</CODE><BR><CODE>      (Eval : sig</CODE><BR><CODE>                type game = Rep.game</CODE><BR><CODE>                val evaluate : bool -&gt; game -&gt; int</CODE><BR><CODE>                val moreI : int</CODE><BR><CODE>                val lessI : int</CODE><BR><CODE>                val is_leaf : bool -&gt; game -&gt; bool</CODE><BR><CODE>                val is_stable : bool -&gt; game -&gt; bool</CODE><BR><CODE>                type state = | G | P | N | C</CODE><BR><CODE>                val state_of : bool -&gt; game -&gt; state</CODE><BR><CODE>              end) -&gt;</CODE><BR><CODE>      sig</CODE><BR><CODE>        type game = Rep.game</CODE><BR><CODE>        and move = Rep.move</CODE><BR><CODE>        val alphabeta : int -&gt; bool -&gt; game -&gt; move</CODE><BR><CODE>      end</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Implementation.</H5>The parametric module <TT>FAlphabetaO</TT> makes explicit the
partition of the type <TT>game</TT> between the two parameters
<TT>Rep</TT> and <TT>Eval</TT>. This module has six functions and
two exceptions. The player <TT>true</TT> searches to maximize the
score while the player <TT>false</TT> seeks to minimize the score.
The function <TT>maxmin_iter</TT> calculates the maximum of the best
score for the branches based on a move of player <TT>true</TT> and
the pruning parameter <FONT FACE=symbol>a</FONT>.<BR>
<BR>
The function <TT>maxmin</TT> takes four parameters: <TT>depth</TT>, which
indicates the actual calculation depth, <TT>node</TT>, a game position,
and <FONT FACE=symbol>a</FONT> and <FONT FACE=symbol>b</FONT>, the pruning parameters. If the node is a
leaf of the tree or if the maximum depth is reached, the function will
return its evaluation of the position. If this is not the case, the
function applies
<TT>maxmin_iter</TT>
to all of the legal moves of player <TT>true</TT>, 
passing it the search function,
diminishing the depth remaining (<TT>minmax</TT>). The latter
searches to minimize the score resulting from the response of player
<TT>false</TT>.<BR>
<BR>
The movements are implemented using exceptions. If the move <FONT FACE=symbol>b</FONT>
is found in the iteration across the legal moves from the function
<TT>maxmin</TT>, then it is returned immediately, the value being
propagated using an exception. The functions <TT>minmax_iter</TT> and
<TT>minmax</TT> provide the equivalents for the other player. The
function <TT>search</TT> determines the move to play based on the
best score found in the lists of scores and moves.<BR>
<BR>
The principal function <TT>alphabeta</TT> of this module calculates the
legal moves from a given position for the requested player,
searches down to the requested depth, and returns the best move.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>FAlphabetaO<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Rep<CODE> </CODE><CODE>:</CODE><CODE> </CODE>REPRESENTATION<TT>)</TT><CODE> </CODE><CODE> </CODE><TT>(</TT>Eval<CODE> </CODE><CODE>:</CODE><CODE> </CODE>EVAL<CODE> </CODE><B>with</B><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<TT>)</TT><CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.move<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>AlphaMovement<CODE> </CODE><B>of</B><CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>BetaMovement<CODE> </CODE><B>of</B><CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>maxmin_iter<CODE> </CODE>node<CODE> </CODE>minmax_cur<CODE> </CODE>beta<CODE> </CODE>alpha<CODE> </CODE>cp<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>alpha_resu<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>max<CODE> </CODE>alpha<CODE> </CODE><TT>(</TT>minmax_cur<CODE> </CODE><TT>(</TT>Rep.play<CODE> </CODE><B>true</B><CODE> </CODE>cp<CODE> </CODE>node<TT>)</TT><CODE> </CODE>beta<CODE> </CODE>alpha<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>if</B><CODE> </CODE>alpha_resu<CODE> </CODE><CODE>&gt;=</CODE><CODE> </CODE>beta<CODE> </CODE><B>then</B><CODE> </CODE><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>BetaMovement<CODE> </CODE>alpha_resu<TT>)</TT><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>alpha_resu<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>minmax_iter<CODE> </CODE>node<CODE> </CODE>maxmin_cur<CODE> </CODE>alpha<CODE> </CODE>beta<CODE> </CODE>cp<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>beta_resu<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>min<CODE> </CODE>beta<CODE> </CODE><TT>(</TT>maxmin_cur<CODE> </CODE><TT>(</TT>Rep.play<CODE> </CODE><B>false</B><CODE> </CODE>cp<CODE> </CODE>node<TT>)</TT><CODE> </CODE>alpha<CODE> </CODE>beta<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>if</B><CODE> </CODE>beta_resu<CODE> </CODE><CODE>&lt;=</CODE><CODE> </CODE>alpha<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>AlphaMovement<CODE> </CODE>beta_resu<TT>)</TT><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>beta_resu<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>maxmin<CODE> </CODE>depth<CODE> </CODE>node<CODE> </CODE>alpha<CODE> </CODE>beta<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>depth<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE>Eval.is_stable<CODE> </CODE><B>true</B><CODE> </CODE>node<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>or</B><CODE> </CODE>Eval.is_leaf<CODE> </CODE><B>true</B><CODE> </CODE>node<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE>Eval.evaluate<CODE> </CODE><B>true</B><CODE> </CODE>node<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>prev<CODE> </CODE><CODE>=</CODE><CODE> </CODE>maxmin_iter<CODE> </CODE>node<CODE> </CODE><TT>(</TT>minmax<CODE> </CODE><TT>(</TT>depth<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><CODE> </CODE>beta<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>List.fold_left<CODE> </CODE>prev<CODE> </CODE>alpha<CODE> </CODE><TT>(</TT>Rep.legal_moves<CODE> </CODE><B>true</B><CODE> </CODE>node<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>BetaMovement<CODE> </CODE>a<CODE> </CODE>-&gt;<CODE> </CODE>a<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>minmax<CODE> </CODE>depth<CODE> </CODE>node<CODE> </CODE>beta<CODE> </CODE>alpha<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>depth<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE>Eval.is_stable<CODE> </CODE><B>false</B><CODE> </CODE>node<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>or</B><CODE> </CODE>Eval.is_leaf<CODE> </CODE><B>false</B><CODE> </CODE>node<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE>Eval.evaluate<CODE> </CODE><B>false</B><CODE> </CODE>node<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><B>let</B><CODE> </CODE>prev<CODE> </CODE><CODE>=</CODE><CODE> </CODE>minmax_iter<CODE> </CODE>node<CODE> </CODE><TT>(</TT>maxmin<CODE> </CODE><TT>(</TT>depth<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><CODE> </CODE>alpha<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>List.fold_left<CODE> </CODE>prev<CODE> </CODE>beta<CODE> </CODE><TT>(</TT>Rep.legal_moves<CODE> </CODE><B>false</B><CODE> </CODE>node<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>AlphaMovement<CODE> </CODE>b<CODE> </CODE>-&gt;<CODE> </CODE>b<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>search<CODE> </CODE>a<CODE> </CODE>l1<CODE> </CODE>l2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE><TT>(</TT>l1<CODE>,</CODE>l2<TT>)</TT><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>h1::q1<CODE>,</CODE><CODE> </CODE>h2::q2<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>h1<CODE> </CODE><B>then</B><CODE> </CODE>h2<CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>search<CODE> </CODE>a<CODE> </CODE>q1<CODE> </CODE>q2<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><TT>(</TT><CODE>[],</CODE><CODE> </CODE>[]<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>"AB: "</CODE><CODE>^</CODE><TT>(</TT>string_of_int<CODE> </CODE>a<TT>)</TT><CODE>^</CODE><CODE>" not found"</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><TT>(</TT><CODE>_</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE> </CODE><CODE>_</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE> </CODE><CODE>"AB: length differs"</CODE><CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* val alphabeta : int -&gt; bool -&gt; Rep.game -&gt; Rep.move *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>alphabeta<CODE> </CODE>depth<CODE> </CODE>player<CODE> </CODE>level<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>alpha<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>Eval.lessI<CODE> </CODE><B>and</B><CODE> </CODE>beta<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>Eval.moreI<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>[]<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cpl<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.legal_moves<CODE> </CODE>player<CODE> </CODE>level<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>eval<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><TT>(</TT>List.length<CODE> </CODE>cpl<TT>)</TT><CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.play<CODE> </CODE>player<CODE> </CODE><TT>(</TT>List.nth<CODE> </CODE>cpl<CODE> </CODE>i<TT>)</TT><CODE> </CODE>level<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>minmax<CODE> </CODE><TT>(</TT>depth<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>b<CODE> </CODE><CODE>!</CODE>beta<CODE> </CODE><CODE>!</CODE>alpha<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>l<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>a<CODE> </CODE>::<CODE> </CODE><CODE>!</CODE>l<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>alpha<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>max<CODE> </CODE><CODE>!</CODE>alpha<CODE> </CODE>a<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE><CODE>!</CODE>alpha<CODE> </CODE><CODE>&gt;=</CODE><CODE> </CODE><CODE>!</CODE>beta<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>BetaMovement<CODE> </CODE><CODE>!</CODE>alpha<TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.play<CODE> </CODE>player<CODE> </CODE><TT>(</TT>List.nth<CODE> </CODE>cpl<CODE> </CODE>i<TT>)</TT><CODE> </CODE>level<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>maxmin<CODE> </CODE><TT>(</TT>depth<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>a<CODE> </CODE><CODE>!</CODE>alpha<CODE> </CODE><CODE>!</CODE>beta<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>l<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>b<CODE> </CODE>::<CODE> </CODE><CODE>!</CODE>l<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>beta<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>min<CODE> </CODE><CODE>!</CODE>beta<CODE> </CODE>b<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE><CODE>!</CODE>beta<CODE> </CODE><CODE>&lt;=</CODE><CODE> </CODE><CODE>!</CODE>alpha<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>AlphaMovement<CODE> </CODE><CODE>!</CODE>beta<TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE><CODE>!</CODE>alpha<CODE> </CODE><B>else</B><CODE> </CODE><CODE>!</CODE>beta<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>BetaMovement<CODE> </CODE>a<CODE> </CODE>-&gt;<CODE> </CODE>a<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE>AlphaMovement<CODE> </CODE>b<CODE> </CODE>-&gt;<CODE> </CODE>b<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>l<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>List.rev<CODE> </CODE><CODE>!</CODE>l<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>search<CODE> </CODE>eval<CODE> </CODE><CODE>!</CODE>l<CODE> </CODE>cpl<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module FAlphabetaO :</CODE><BR><CODE>  functor(Rep : REPRESENTATION) -&gt;</CODE><BR><CODE>    functor</CODE><BR><CODE>      (Eval : sig</CODE><BR><CODE>                type game = Rep.game</CODE><BR><CODE>                val evaluate : bool -&gt; game -&gt; int</CODE><BR><CODE>                val moreI : int</CODE><BR><CODE>                val lessI : int</CODE><BR><CODE>                val is_leaf : bool -&gt; game -&gt; bool</CODE><BR><CODE>                val is_stable : bool -&gt; game -&gt; bool</CODE><BR><CODE>                type state = | G | P | N | C</CODE><BR><CODE>                val state_of : bool -&gt; game -&gt; state</CODE><BR><CODE>              end) -&gt;</CODE><BR><CODE>      sig</CODE><BR><CODE>        type game = Rep.game</CODE><BR><CODE>        and move = Rep.move</CODE><BR><CODE>        exception AlphaMovement of int</CODE><BR><CODE>        exception BetaMovement of int</CODE><BR><CODE>        val maxmin_iter :</CODE><BR><CODE>          Rep.game -&gt;</CODE><BR><CODE>          (Rep.game -&gt; int -&gt; int -&gt; int) -&gt; int -&gt; int -&gt; Rep.move -&gt; int</CODE><BR><CODE>        val minmax_iter :</CODE><BR><CODE>          Rep.game -&gt;</CODE><BR><CODE>          (Rep.game -&gt; int -&gt; int -&gt; int) -&gt; int -&gt; int -&gt; Rep.move -&gt; int</CODE><BR><CODE>        val maxmin : int -&gt; Eval.game -&gt; int -&gt; int -&gt; int</CODE><BR><CODE>        val minmax : int -&gt; Eval.game -&gt; int -&gt; int -&gt; int</CODE><BR><CODE>        val search : int -&gt; int list -&gt; 'a list -&gt; 'a</CODE><BR><CODE>        val alphabeta : int -&gt; bool -&gt; Rep.game -&gt; Rep.move</CODE><BR><CODE>      end</CODE><BR>

</PRE>
<BR>
<BR>
We may close module <TT>FAlphabetaO</TT> by associating with it the
following signature:<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>FAlphabeta<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>FAlphabetaO<CODE> </CODE><CODE>:</CODE><CODE> </CODE>FALPHABETA<TT>)</TT><CODE> </CODE>;;<BR><CODE>module FAlphabeta : FALPHABETA</CODE><BR>

</PRE>
<BR>
<BR>
This latter module may be used with many different game
representations and functions to play different games.<BR>
<BR>
<A NAME="toc231"></A>
<H3> Organization of a Game Program</H3>
The organization of a program for a two player game may be separated
into a portion specific to the game in question as well as a portion
applicable to all sorts of games. For this, we propose using several
parametric modules parameterized by specific modules, permitting us to
avoid the need to rewrite the common portions each time. Figure
<A HREF="book-ora160.html#fig-orgjeux">17.4</A> shows the chosen organization.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora069.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.4: Organization of a game application.</DIV><BR>

<A NAME="fig-orgjeux"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The modules with no highlighting correspond to the common parts of the
application. These are the parametric modules. We see again the
functor <TT>FAlphabeta</TT>. The modules with gray highlighting are the
modules designed specifically for a given game. The three principal
modules are the representation of the game (<TT>J_Repr</TT>),
display of the game (<TT>J_Disp</TT>), and the evaluation function
(<TT>J_Eval</TT>). The modules with rounded gray borders are
obtained by applying the parametric modules to the simple modules
specific to the game.
<BR>
<BR>
The module <TT>FAlphabeta</TT> has already been described. The two
other common modules are <TT>FMain</TT>, containing the main loop, and
<TT>FSkeleton</TT>, that manages the players.<BR>
<BR>

<H4> Module <TT>FMain</TT></H4>Module <TT>FMain</TT> contains the main loop for execution of a game
program. It is parameterized using the signature module
<TT>SKELETON</TT>, describing the interaction with a player using the
following definition:<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>SKELETON<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>sig</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>home<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>init<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><TT>(</TT>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>again<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>bool<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>exit<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>won<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>lost<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>nil<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Won<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Lost<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Nil<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type SKELETON =</CODE><BR><CODE>  sig</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; (unit -&gt; unit) * (unit -&gt; unit)</CODE><BR><CODE>    val again : unit -&gt; bool</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    exception Won</CODE><BR><CODE>    exception Lost</CODE><BR><CODE>    exception Nil</CODE><BR><CODE>  end</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR>

</PRE>
<BR>
<BR>
The function <TT>init</TT> constructs a pair of action functions for
each player. The other functions control the interactions. Module
<TT>FMain</TT> contains two functions: <TT>play_game</TT> which
alternates between the players, and <TT>main</TT> which controls the
main loop.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>FMain<CODE> </CODE><TT>(</TT>P<CODE> </CODE><CODE>:</CODE><CODE> </CODE>SKELETON<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>play_game<CODE> </CODE>movements<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><CODE> </CODE><TT>(</TT>fst<CODE> </CODE>movements<TT>)</TT><CODE> </CODE>()<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>snd<CODE> </CODE>movements<TT>)</TT><CODE> </CODE>()<CODE> </CODE><B>done</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>main<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>let</B><CODE> </CODE>finished<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><B>false</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>P.home<CODE> </CODE>();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE>not<CODE> </CODE><CODE>!</CODE>finished<CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><B>try</B><CODE> </CODE><CODE> </CODE>play_game<CODE> </CODE><TT>(</TT>P.init<CODE> </CODE>()<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>P<CODE>.</CODE>Won<CODE> </CODE>-&gt;<CODE> </CODE>P.won<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>P<CODE>.</CODE>Lost<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>P.lost<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>P<CODE>.</CODE>Nil<CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>P.nil<CODE> </CODE>()<CODE> </CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>finished<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>not<CODE> </CODE><TT>(</TT>P.again<CODE> </CODE>()<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>P.exit<CODE> </CODE>()<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module FMain :</CODE><BR><CODE>  functor(P : SKELETON) -&gt;</CODE><BR><CODE>    sig</CODE><BR><CODE>      val play_game : (unit -&gt; 'a) * (unit -&gt; 'b) -&gt; unit</CODE><BR><CODE>      val main : unit -&gt; unit</CODE><BR><CODE>    end</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Module <TT>FSkeleton</TT></H4>Parametric module <TT>FSkeleton</TT> controls the moves of each
player according to the rules provided at the start of the section
based on the nature of the players (automated or not) and the order of
the players. It needs various parameters to represent the game, game
states, the evaluation function, and the <FONT FACE=symbol>a</FONT> <FONT FACE=symbol>b</FONT> search as
described in figure <A HREF="book-ora160.html#fig-orgjeux">17.4</A>.<BR>
<BR>
We start with the signature needed for game display.
<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE><B>type</B><CODE> </CODE>DISPLAY<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>sig</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>home<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>exit<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>won<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>lost<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>nil<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>init<CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>position<CODE> </CODE><CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE>move<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>unit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>choice<CODE> </CODE><CODE>:</CODE><CODE> </CODE>bool<CODE> </CODE>-&gt;<CODE> </CODE><CODE> </CODE>game<CODE> </CODE>-&gt;<CODE> </CODE>move<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>q_player<CODE> </CODE><CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>bool<CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>q_begin<CODE> </CODE><CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>bool<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>q_continue<CODE> </CODE><CODE>:</CODE><CODE> </CODE>unit<CODE> </CODE>-&gt;<CODE> </CODE>bool<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module type DISPLAY =</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game</CODE><BR><CODE>    and move</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; unit</CODE><BR><CODE>    val position : bool -&gt; move -&gt; game -&gt; game -&gt; unit</CODE><BR><CODE>    val choice : bool -&gt; game -&gt; move</CODE><BR><CODE>    val q_player : unit -&gt; bool</CODE><BR><CODE>    val q_begin : unit -&gt; bool</CODE><BR><CODE>    val q_continue : unit -&gt; bool</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
It is worth noting that the representation of the game and of the
moves must be shared by all the parametric modules, which constrain the 
types. The two principal functions are <TT>playH</TT> and <TT>playM</TT>, 
respectively controlling the move of a human player (using the
function <TT>Disp.choice</TT>) and that of an automated player. The
function <TT>init</TT> determines the nature of the players and the sorts
of responses for <TT>Disp.q_player</TT>.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>FSkeleton<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Rep<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>REPRESENTATION<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Disp<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>DISPLAY<CODE> </CODE><B>with</B><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<CODE> </CODE><B>and</B><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.move<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Eval<CODE> </CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>EVAL<CODE> </CODE><B>with</B><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Alpha<CODE> </CODE><CODE>:</CODE><CODE> </CODE>ALPHABETA<CODE> </CODE><B>with</B><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.game<CODE> </CODE><B>and</B><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Rep.move<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>depth<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>4</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Won<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Lost<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Nil<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>won<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.won<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lost<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.lost<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>nil<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.nil<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>again<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.q_continue<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>play_game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><TT>(</TT>Rep.game_start()<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>exit<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.exit<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>home<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.home<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>playH<CODE> </CODE>player<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>choice<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.choice<CODE> </CODE>player<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>old_game<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>play_game<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>Rep.play<CODE> </CODE>player<CODE> </CODE>choice<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Disp.position<CODE> </CODE>player<CODE> </CODE>choice<CODE> </CODE>old_game<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Eval.state_of<CODE> </CODE>player<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Eval<CODE>.</CODE>P<CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Lost<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Eval<CODE>.</CODE>G<CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Won<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Eval<CODE>.</CODE>N<CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Nil<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>()<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>playM<CODE> </CODE>player<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>choice<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Alpha.alphabeta<CODE> </CODE><CODE>!</CODE>depth<CODE> </CODE>player<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>old_game<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>play_game<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>Rep.play<CODE> </CODE>player<CODE> </CODE>choice<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Disp.position<CODE> </CODE>player<CODE> </CODE>choice<CODE> </CODE>old_game<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>Eval.state_of<CODE> </CODE>player<CODE> </CODE><CODE>!</CODE>play_game<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Eval<CODE>.</CODE>G<CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Won<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Eval<CODE>.</CODE>P<CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Lost<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Eval<CODE>.</CODE>N<CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Nil<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>init<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.q_player<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Disp.q_player()<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>play_game<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>Rep.game_start<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Disp.init<CODE> </CODE>()<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE><TT>(</TT>a<CODE>,</CODE>b<TT>)</TT><CODE> </CODE><B>with</B><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>true</B><CODE>,</CODE><B>true</B><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>playM<CODE> </CODE><B>true</B><CODE>,</CODE><CODE> </CODE>playM<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><B>true</B><CODE>,</CODE><B>false</B><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>playM<CODE> </CODE><B>true</B><CODE>,</CODE><CODE> </CODE>playH<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><B>false</B><CODE>,</CODE><B>true</B><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>playH<CODE> </CODE><B>true</B><CODE>,</CODE><CODE> </CODE>playM<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><B>false</B><CODE>,</CODE><B>false</B><CODE> </CODE>-&gt;<CODE> </CODE>playH<CODE> </CODE><B>true</B><CODE>,</CODE><CODE> </CODE>playH<CODE> </CODE><B>false</B><BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module FSkeleton :</CODE><BR><CODE>  functor(Rep : REPRESENTATION) -&gt;</CODE><BR><CODE>    functor</CODE><BR><CODE>      (Disp : sig</CODE><BR><CODE>                type game = Rep.game</CODE><BR><CODE>                and move = Rep.move</CODE><BR><CODE>                val home : unit -&gt; unit</CODE><BR><CODE>                val exit : unit -&gt; unit</CODE><BR><CODE>                val won : unit -&gt; unit</CODE><BR><CODE>                val lost : unit -&gt; unit</CODE><BR><CODE>                val nil : unit -&gt; unit</CODE><BR><CODE>                val init : unit -&gt; unit</CODE><BR><CODE>                val position : bool -&gt; move -&gt; game -&gt; game -&gt; unit</CODE><BR><CODE>                val choice : bool -&gt; game -&gt; move</CODE><BR><CODE>                val q_player : unit -&gt; bool</CODE><BR><CODE>                val q_begin : unit -&gt; bool</CODE><BR><CODE>                val q_continue : unit -&gt; bool</CODE><BR><CODE>              end) -&gt;</CODE><BR><CODE>      functor</CODE><BR><CODE>        (Eval : sig</CODE><BR><CODE>                  type game = Rep.game</CODE><BR><CODE>                  val evaluate : bool -&gt; game -&gt; int</CODE><BR><CODE>                  val moreI : int</CODE><BR><CODE>                  val lessI : int</CODE><BR><CODE>                  val is_leaf : bool -&gt; game -&gt; bool</CODE><BR><CODE>                  val is_stable : bool -&gt; game -&gt; bool</CODE><BR><CODE>                  type state = | G | P | N | C</CODE><BR><CODE>                  val state_of : bool -&gt; game -&gt; state</CODE><BR><CODE>                end) -&gt;</CODE><BR><CODE>        functor</CODE><BR><CODE>          (Alpha : sig</CODE><BR><CODE>                     type game = Rep.game</CODE><BR><CODE>                     and move = Rep.move</CODE><BR><CODE>                     val alphabeta : int -&gt; bool -&gt; game -&gt; move</CODE><BR><CODE>                   end) -&gt;</CODE><BR><CODE>          sig</CODE><BR><CODE>            val depth : int ref</CODE><BR><CODE>            exception Won</CODE><BR><CODE>            exception Lost</CODE><BR><CODE>            exception Nil</CODE><BR><CODE>            val won : unit -&gt; unit</CODE><BR><CODE>            val lost : unit -&gt; unit</CODE><BR><CODE>            val nil : unit -&gt; unit</CODE><BR><CODE>            val again : unit -&gt; bool</CODE><BR><CODE>            val play_game : Disp.game ref</CODE><BR><CODE>            val exit : unit -&gt; unit</CODE><BR><CODE>            val home : unit -&gt; unit</CODE><BR><CODE>            val playH : bool -&gt; unit -&gt; unit</CODE><BR><CODE>            val playM : bool -&gt; unit -&gt; unit</CODE><BR><CODE>            val init : unit -&gt; (unit -&gt; unit) * (unit -&gt; unit)</CODE><BR><CODE>          end</CODE><BR>

</PRE>
<BR>
<BR>
The independent parts of the game are thus implemented. One may then
begin programming different sorts of games. This modular organization
facilitates making modifications to the movement scheme or to the
evaluation function for a game as we shall soon see.<BR>
<BR>
<A NAME="toc232"></A>
<H3> Connect Four</H3>
We will next examine a simple game, a vertical tic-tac-toe, known 
as Connect Four. The game is represented by seven columns each consisting
of six lines. In turn, a player places on a column a piece of his
color, where it then falls down to the lowest free location in this
column. If a column is completely filled, neither player is permitted
to play there. The game ends when one of the players has built a line
of four pieces in a row (horizontal, vertical, or diagonal), at which
point this player has won, or when all the columns are filled with
pieces, in which the outcome is a draw. Figure <A HREF="book-ora160.html#fig-p4">17.5</A> shows a
completed game.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora070.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.5: An example of Connect Four.</DIV><BR>

<A NAME="fig-p4"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>Note the ``winning'' line of four gray pieces in a diagonal, going
down and to the right.<BR>
<BR>

<H5> Game Representation: module <TT>C4_rep</TT>.</H5>
We choose for this game a matrix-based representation. Each element
of the matrix is either empty, or contains a player's piece. 
A move is numbered by the column. The legal moves are the
columns in which the final (top) row is not filled.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>C4_rep<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>cell<CODE> </CODE><CODE>=</CODE><CODE> </CODE>A<CODE> </CODE><CODE>|</CODE><CODE> </CODE>B<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Empty<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cell<CODE> </CODE>array<CODE> </CODE>array<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>col<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>7</CODE><CODE> </CODE><B>and</B><CODE> </CODE>row<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>6</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>game_start<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.create_matrix<CODE> </CODE>row<CODE> </CODE>col<CODE> </CODE>Empty<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>legal_moves<CODE> </CODE>b<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>[]<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE>col<CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>do</B><CODE> </CODE><B>if</B><CODE> </CODE>m<CODE>.</CODE><TT>(</TT>row<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE>.</CODE><TT>(</TT>c<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Empty<CODE> </CODE><B>then</B><CODE> </CODE>l<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><TT>(</TT>c<CODE>+</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>::<CODE> </CODE><CODE>!</CODE>l<CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>l<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>augment<CODE> </CODE>mat<CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>row<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>while</B><CODE> </CODE><CODE>!</CODE>l<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE>mat<CODE>.</CODE><TT>(</TT><CODE>!</CODE>l<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE>.</CODE><TT>(</TT>c<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Empty<CODE> </CODE><B>do</B><CODE> </CODE><CODE> </CODE>decr<CODE> </CODE>l<CODE> </CODE><B>done</B><CODE> </CODE>;<CODE> </CODE><CODE>!</CODE>l<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>player_gen<CODE> </CODE>cp<CODE> </CODE>m<CODE> </CODE>e<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>mj<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.map<CODE> </CODE>Array.copy<CODE> </CODE><CODE> </CODE>m<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE>mj<CODE>.</CODE><TT>(</TT><TT>(</TT>augment<CODE> </CODE>mj<CODE> </CODE>cp<TT>)</TT><CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE>.</CODE><TT>(</TT>cp<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>e<CODE> </CODE>;<CODE> </CODE>mj<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>play<CODE> </CODE>b<CODE> </CODE>cp<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>if</B><CODE> </CODE>b<CODE> </CODE><B>then</B><CODE> </CODE>player_gen<CODE> </CODE>cp<CODE> </CODE>m<CODE> </CODE>A<CODE> </CODE><B>else</B><CODE> </CODE>player_gen<CODE> </CODE>cp<CODE> </CODE>m<CODE> </CODE>B<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module C4_rep :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type cell = | A | B | Empty</CODE><BR><CODE>    and game = cell array array</CODE><BR><CODE>    and move = int</CODE><BR><CODE>    val col : int</CODE><BR><CODE>    val row : int</CODE><BR><CODE>    val game_start : unit -&gt; cell array array</CODE><BR><CODE>    val legal_moves : 'a -&gt; cell array array -&gt; int list</CODE><BR><CODE>    val augment : cell array array -&gt; int -&gt; int</CODE><BR><CODE>    val player_gen : int -&gt; cell array array -&gt; cell -&gt; cell array array</CODE><BR><CODE>    val play : bool -&gt; int -&gt; cell array array -&gt; cell array array</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
We may easily verify if this module accepts the constraints of the
signature <TT>REPRESENTATION</TT>.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_rep_T<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>C4_rep<CODE> </CODE><CODE>:</CODE><CODE> </CODE>REPRESENTATION<TT>)</TT><CODE> </CODE>;;<BR><CODE>module C4_rep_T : REPRESENTATION</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Game Display: Module <TT>C4_text</TT>.</H5>
Module <TT>C4_text</TT> describes a text-based interface for the game
Connect Four that is compatible with the signature <TT>DISPLAY</TT>. It
it is not particularly sophisticated, but, nonetheless, demonstrates how
modules are assembled together.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>C4_text<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>open</B><CODE> </CODE>C4_rep<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>C4_rep.game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>C4_rep.move<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>print_game<CODE> </CODE>mat<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>row<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>downto</B><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE>col<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>mat<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE>.</CODE><TT>(</TT>c<TT>)</TT><CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>A<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><CODE>"X "</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>B<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><CODE>"O "</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Empty<CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><CODE>". "</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline<CODE> </CODE>()<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>home<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"C4 ...\n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>exit<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"Bye for now ... \n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>question<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE>s;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>" y/n ? "</CODE><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>read_line()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"y"</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>q_begin<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Would you like to begin?"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>q_continue<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Play again?"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>q_player<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Is there to be a machine player ?"</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>won<CODE> </CODE><CODE> </CODE>()<CODE>=</CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"The first player won"</CODE><CODE> </CODE>;<CODE> </CODE>print_newline<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lost<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"The first player lost"</CODE><CODE> </CODE>;<CODE> </CODE>print_newline<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>nil<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"Stalemate"</CODE><CODE> </CODE>;<CODE> </CODE>print_newline<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>init<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"X: 1st player   O: 2nd player"</CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline<CODE> </CODE>()<CODE> </CODE>;<CODE> </CODE>print_newline<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_game<CODE> </CODE><TT>(</TT>game_start<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<CODE> </CODE>print_newline()<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>position<CODE> </CODE>b<CODE> </CODE>c<CODE> </CODE>aj<CODE> </CODE>j<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_game<CODE> </CODE>j<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_move<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>'1'</CODE><CODE>..</CODE><CODE>'7'</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>true</B><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Move<CODE> </CODE><B>of</B><CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>choice<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><TT>(</TT><CODE>"Choose player"</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE><CODE>"1"</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>"2"</CODE><TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>" : "</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>legal_moves<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>try</B><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><B>true</B><CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE>read_line()<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><TT>(</TT><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>String.length<CODE> </CODE>i<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT>is_move<CODE> </CODE><CODE> </CODE>i<CODE>.[</CODE><CODE>0</CODE><CODE>]</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE><B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>int_of_char<CODE> </CODE>i<CODE>.[</CODE><CODE>0</CODE><CODE>]</CODE><TT>)</TT><CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT>int_of_char<CODE> </CODE><CODE>'0'</CODE><TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>if</B><CODE> </CODE>List.mem<CODE> </CODE>c<CODE> </CODE>l<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>Move<CODE> </CODE>c<TT>)</TT><CODE> </CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"Invalid move - try again"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.hd<CODE> </CODE>l<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><CODE> </CODE>Move<CODE> </CODE>i<CODE> </CODE>-&gt;<CODE> </CODE>i<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>List.hd<CODE> </CODE>l<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module C4_text :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game = C4_rep.game</CODE><BR><CODE>    and move = C4_rep.move</CODE><BR><CODE>    val print_game : C4_rep.cell array array -&gt; unit</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val question : string -&gt; bool</CODE><BR><CODE>    val q_begin : unit -&gt; bool</CODE><BR><CODE>    val q_continue : unit -&gt; bool</CODE><BR><CODE>    val q_player : unit -&gt; bool</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; unit</CODE><BR><CODE>    val position : 'a -&gt; 'b -&gt; 'c -&gt; C4_rep.cell array array -&gt; unit</CODE><BR><CODE>    val is_move : char -&gt; bool</CODE><BR><CODE>    exception Move of int</CODE><BR><CODE>    val choice : bool -&gt; C4_rep.cell array array -&gt; int</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
We may immediately verify that this conforms to the constraints of the
signature <TT>DISPLAY</TT><BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_text_T<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>C4_text<CODE> </CODE><CODE>:</CODE><CODE> </CODE>DISPLAY<TT>)</TT><CODE> </CODE>;;<BR><CODE>module C4_text_T : DISPLAY</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Evaluation Function: module <TT>C4_eval</TT>.</H5> The quality of a game player depends primarily on the position
evaluation function. Module <TT>C4_eval</TT> defines 
<TT>evaluate</TT>, which evaluates the value of a position for the
specified player. This function calls <TT>eval_bloc</TT>
for the four compass directions as well as the diagonals.
<TT>eval_bloc</TT> then calls <TT>eval_four</TT> to
calculate the number of pieces in the requested line. Table
<TT>value</TT> provides the value of a block containing 0, 1, 2, or 3
pieces of the same color. The exception <TT>Four</TT> is raised
when 4 pieces are aligned.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>C4_eval<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><CODE> </CODE><B>open</B><CODE> </CODE>C4_rep<CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>C4_rep.game<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>value<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Array.of_list<CODE> </CODE><CODE>[</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>5</CODE><CODE>0</CODE><CODE>]</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Four<CODE> </CODE><B>of</B><CODE> </CODE>int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Nil_Value<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Arg_invalid<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lessI<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>moreI<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>eval_four<CODE> </CODE>m<CODE> </CODE>l_dep<CODE> </CODE>c_dep<CODE> </CODE>delta_l<CODE> </CODE>delta_c<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>and</B><CODE> </CODE>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>Empty<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>c_dep<CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>l_dep<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>try</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>4</CODE><CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>y<CODE>&lt;</CODE><CODE>0</CODE><CODE> </CODE><B>or</B><CODE> </CODE><CODE>!</CODE>y<CODE>&gt;=</CODE>row<CODE> </CODE><B>or</B><CODE> </CODE><CODE>!</CODE>x<CODE>&lt;</CODE><CODE>0</CODE><CODE> </CODE><B>or</B><CODE> </CODE><CODE>!</CODE>x<CODE>&gt;=</CODE>col<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE>Arg_invalid<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><B>match</B><CODE> </CODE>m<CODE>.</CODE><TT>(</TT><CODE>!</CODE>y<TT>)</TT><CODE>.</CODE><TT>(</TT><CODE>!</CODE>x<TT>)</TT><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>A<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>B<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE>Nil_Value<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>incr<CODE> </CODE>n<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>Four<CODE> </CODE>moreI<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>e<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>A<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>B<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>A<CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE>Nil_Value<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>incr<CODE> </CODE>n<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE><B>then</B><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>Four<CODE> </CODE>lessI<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>e<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>B;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Empty<CODE> </CODE>-&gt;<CODE> </CODE>()<CODE> </CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>x<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>!</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>delta_c<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>y<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>!</CODE>y<CODE> </CODE><CODE>+</CODE><CODE> </CODE>delta_l<CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>value<CODE>.</CODE><TT>(</TT><CODE>!</CODE>n<TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE><CODE>!</CODE>e<CODE>=</CODE>A<CODE> </CODE><B>then</B><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Nil_Value<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Arg_invalid<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>e<CODE> </CODE>cmin<CODE> </CODE>cmax<CODE> </CODE>lmin<CODE> </CODE>lmax<CODE> </CODE>dx<CODE> </CODE>dy<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>c<CODE>=</CODE>cmin<CODE> </CODE><B>to</B><CODE> </CODE>cmax<CODE> </CODE><B>do</B><CODE> </CODE><B>for</B><CODE> </CODE>l<CODE>=</CODE>lmin<CODE> </CODE><B>to</B><CODE> </CODE>lmax<CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>e<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>!</CODE>e<CODE> </CODE><CODE>+</CODE><CODE> </CODE>eval_four<CODE> </CODE>m<CODE> </CODE>l<CODE> </CODE>c<CODE> </CODE>dx<CODE> </CODE>dy<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>evaluate<CODE> </CODE>b<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><B>let</B><CODE> </CODE>evaluation<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE>(* evaluation of rows *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>evaluation<CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>row<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>col<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* evaluation of columns *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>evaluation<CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>col<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>row<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* diagonals coming from the first line (to the right) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>evaluation<CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>col<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>row<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* diagonals coming from the first line (to the left) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>evaluation<CODE> </CODE><CODE>1</CODE><CODE> </CODE><TT>(</TT>row<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>col<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* diagonals coming from the last line (to the right) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>evaluation<CODE> </CODE><CODE>3</CODE><CODE> </CODE><TT>(</TT>col<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>row<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* diagonals coming from the last line (to the left) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>eval_bloc<CODE> </CODE>m<CODE> </CODE>evaluation<CODE> </CODE><CODE>1</CODE><CODE> </CODE><TT>(</TT>row<CODE>-</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><CODE>3</CODE><CODE> </CODE><TT>(</TT>col<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>evaluation<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE>Four<CODE> </CODE>v<CODE> </CODE>-&gt;<CODE> </CODE>v<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_leaf<CODE> </CODE>b<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>evaluate<CODE> </CODE>b<CODE> </CODE>m<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>v<CODE>=</CODE>moreI<CODE> </CODE><B>or</B><CODE> </CODE>v<CODE>=</CODE>lessI<CODE> </CODE><B>or</B><CODE> </CODE>legal_moves<CODE> </CODE>b<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_stable<CODE> </CODE>b<CODE> </CODE>j<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>true</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>state<CODE> </CODE><CODE>=</CODE><CODE> </CODE>G<CODE> </CODE><CODE>|</CODE><CODE> </CODE>P<CODE> </CODE><CODE>|</CODE><CODE> </CODE>N<CODE> </CODE><CODE>|</CODE><CODE> </CODE>C<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>state_of<CODE> </CODE>player<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>evaluate<CODE> </CODE>player<CODE> </CODE>m<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><B>if</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>moreI<CODE> </CODE><B>then</B><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>G<CODE> </CODE><B>else</B><CODE> </CODE>P<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>lessI<CODE> </CODE><B>then</B><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>P<CODE> </CODE><B>else</B><CODE> </CODE>G<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>legal_moves<CODE> </CODE>player<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<CODE> </CODE><B>then</B><CODE> </CODE>N<CODE> </CODE><B>else</B><CODE> </CODE>C<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module C4_eval :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game = C4_rep.game</CODE><BR><CODE>    val value : int array</CODE><BR><CODE>    exception Four of int</CODE><BR><CODE>    exception Nil_Value</CODE><BR><CODE>    exception Arg_invalid</CODE><BR><CODE>    val lessI : int</CODE><BR><CODE>    val moreI : int</CODE><BR><CODE>    val eval_four :</CODE><BR><CODE>      C4_rep.cell array array -&gt; int -&gt; int -&gt; int -&gt; int -&gt; int</CODE><BR><CODE>    val eval_bloc :</CODE><BR><CODE>      C4_rep.cell array array -&gt;</CODE><BR><CODE>      int ref -&gt; int -&gt; int -&gt; int -&gt; int -&gt; int -&gt; int -&gt; unit</CODE><BR><CODE>    val evaluate : 'a -&gt; C4_rep.cell array array -&gt; int</CODE><BR><CODE>    val is_leaf : 'a -&gt; C4_rep.cell array array -&gt; bool</CODE><BR><CODE>    val is_stable : 'a -&gt; 'b -&gt; bool</CODE><BR><CODE>    type state = | G | P | N | C</CODE><BR><CODE>    val state_of : bool -&gt; C4_rep.cell array array -&gt; state</CODE><BR><CODE>  end</CODE><BR>

</PRE>

<BR>
<BR>
Module <TT>C4_eval</TT> is compatible with the constraints of
signature <TT>EVAL</TT>.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_eval_T<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>C4_eval<CODE> </CODE><CODE>:</CODE><CODE> </CODE>EVAL<TT>)</TT><CODE> </CODE>;;<BR><CODE>module C4_eval_T : EVAL</CODE><BR>

</PRE>
<BR>
<BR>
To play two evaluation functions against one another, it is necessary
to modify <TT>evaluate</TT> to apply the proper evaluation
function for each player.<BR>
<BR>

<H5> Assembly of the modules</H5> All the components needed to realize the game of Connect Four
are now implemented. We only need assemble them together based on the
schema of diagram <A HREF="book-ora160.html#fig-orgjeux">17.4</A>. First, we construct 
<TT>C4_skeleton</TT>, which is the application of parameter module
<TT>FSkeleton</TT> to modules <TT> C4_rep</TT>, <TT>C4_text</TT>,
<TT>C4_eval</TT> and the result of the application of parametric
module <TT>FAlphaBeta</TT> to <TT> C4_rep</TT> and
<TT>C4_eval</TT>.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_skeleton<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>FSkeleton<CODE> </CODE><TT>(</TT>C4_rep<TT>)</TT><CODE> </CODE><TT>(</TT>C4_text<TT>)</TT><CODE> </CODE><TT>(</TT>C4_eval<TT>)</TT><CODE> </CODE><CODE> </CODE><TT>(</TT>FAlphabeta<CODE> </CODE><TT>(</TT>C4_rep<TT>)</TT><CODE> </CODE><TT>(</TT>C4_eval<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>module C4_skeleton :</CODE><BR><CODE>  sig</CODE><BR><CODE>    val depth : int ref</CODE><BR><CODE>    exception Won</CODE><BR><CODE>    exception Lost</CODE><BR><CODE>    exception Nil</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    val again : unit -&gt; bool</CODE><BR><CODE>    val play_game : C4_text.game ref</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val playH : bool -&gt; unit -&gt; unit</CODE><BR><CODE>    val playM : bool -&gt; unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; (unit -&gt; unit) * (unit -&gt; unit)</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
We then obtain the principal module <TT>C4_main</TT> by applying
parametric module <TT>FMain</TT> on the result of the preceding
application <TT>C4_skeleton</TT><BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_main<CODE> </CODE><CODE>=</CODE><CODE> </CODE>FMain<TT>(</TT>C4_skeleton<TT>)</TT><CODE> </CODE>;;<BR><CODE>module C4_main :</CODE><BR><CODE>  sig</CODE><BR><CODE>    val play_game : (unit -&gt; 'a) * (unit -&gt; 'b) -&gt; unit</CODE><BR><CODE>    val main : unit -&gt; unit</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
The game is initiated by the application of function <TT>C4_main.main</TT> on 
<TT>()</TT>.<BR>
<BR>

<H5> Testing the Game.</H5>Once the general game skeleton has been written, games may be played
in various ways. Two human players may play against each other, with
the program merely verifying the validity of the moves; a person may
play against a programmed player; or programs may play against each
other. While this last mode might not be interesting for the human,
it does make it easy to run tests without having to wait for a person's
responses. The following game demonstrates this scenario.<BR>
<BR>
<PRE>
# C4_main.main () ;;
C4 ...
Is there to be a machine player ? y/n ? y
Is there to be a machine player ? y/n ? y
X: 1st player   O: 2nd player

. . . . . . . 
. . . . . . . 
. . . . . . . 
. . . . . . . 
. . . . . . . 
. . . . . . . 
</PRE>Once the initial position is played, player 1 (controlled by the
program) calculates its move which is then applied.<BR>
<BR>
<PRE>
. . . . . . . 
. . . . . . . 
. . . . . . . 
. . . . . . . 
. . . . . . . 
. . . . . X . 
</PRE>Player 2 (always controlled by the program) calculates its response
and the game proceeds, until a game-ending move is found. In this
example, player 1 wins the game based on the following final position:<BR>
<BR>
<PRE>
. O O O . O . 
. X X X . X . 
X O O X . O . 
X X X O . X . 
X O O X X O . 
X O O O X X O 
Player 1 wins
Play again(y/n) ? n
Good-bye ... 
- : unit = ()
</PRE>
<H5> Graphical Interface.</H5>To improve the enjoyment of the game, we define a graphical interface
for the program, by defining a new module, <TT>C4_graph</TT>,
compatible with the signature <TT>DISPLAY</TT>, which opens a
graphical window, controlled by mouse clicks. The text of this module
may be found in the subdirectory <TT>Applications</TT> on the CD-ROM
(see page <A HREF="book-ora007.html#CDROM">??</A>).<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>C4_graph<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>open</B><CODE> </CODE>C4_rep<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>C4_rep.game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>C4_rep.move<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* color of piece *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>ec<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* distance between pieces *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>dec<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* center of first piece *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cote<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>*</CODE>r<CODE> </CODE><CODE>+</CODE><CODE> </CODE>ec<CODE> </CODE><CODE>(* height of a piece looked at like a checker *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>htexte<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* where to place text *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>width<CODE> </CODE><CODE>=</CODE><CODE> </CODE>col<CODE> </CODE><CODE>*</CODE><CODE> </CODE>cote<CODE> </CODE><CODE>+</CODE><CODE> </CODE>ec<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* width of the window *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>height<CODE> </CODE><CODE>=</CODE><CODE> </CODE>row<CODE> </CODE><CODE>*</CODE><CODE> </CODE>cote<CODE> </CODE><CODE>+</CODE><CODE> </CODE>ec<CODE> </CODE><CODE>+</CODE><CODE> </CODE>htexte<CODE> </CODE><CODE>(* height of the window *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>height_of_game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>row<CODE> </CODE><CODE>*</CODE><CODE> </CODE>cote<CODE> </CODE><CODE>+</CODE><CODE> </CODE>ec<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* height of game space *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>hec<CODE> </CODE><CODE>=</CODE><CODE> </CODE>height_of_game<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>7</CODE><CODE> </CODE><CODE> </CODE><CODE>(* line for messages *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lec<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* columns for messages *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>margin<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* margin for buttons *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>xb1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>width<CODE> </CODE><CODE>/</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* position x of button1 *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>xb2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>xb1<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* position x of button2 *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>yb<CODE> </CODE><CODE>=</CODE><CODE> </CODE>hec<CODE> </CODE><CODE>-</CODE><CODE> </CODE>margin<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* position y of the buttons *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>wb<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* width of the buttons *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>hb<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>6</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* height of the buttons *)</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val t2e : int -&gt; int *)</CODE><BR><CODE> </CODE><CODE>(* Convert a matrix coordinate into a graphical coordinate *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>t2e<CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE>dec<CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>(</TT>i<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE>*</CODE>cote<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* The Colors *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cN<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.black<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* trace *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cA<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.red<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Human player *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cB<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.yellow<CODE> </CODE><CODE> </CODE><CODE>(* Machine player *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cF<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.blue<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Game Background color *)</CODE><BR><CODE> </CODE><CODE>(* val draw_table : unit -&gt; unit :  Trace an empty table *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_table<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.clear_graph();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cF;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>width<CODE> </CODE>height_of_game;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cN;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><CODE>0</CODE><CODE> </CODE>height_of_game;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE>width<CODE> </CODE>height_of_game;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>to</B><CODE> </CODE>row<CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>to</B><CODE> </CODE>col<CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_circle<CODE> </CODE><TT>(</TT>t2e<CODE> </CODE>c<TT>)</TT><CODE> </CODE><TT>(</TT>t2e<CODE> </CODE>l<TT>)</TT><CODE> </CODE>r<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val draw_piece : int -&gt; int -&gt; Graphics.color -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* 'draw_piece l c co' draws a piece of color co at coordinates l c *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_piece<CODE> </CODE>l<CODE> </CODE>c<CODE> </CODE>col<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>col;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_circle<CODE> </CODE><TT>(</TT>t2e<CODE> </CODE>c<TT>)</TT><CODE> </CODE><TT>(</TT>t2e<CODE> </CODE>l<TT>)</TT><CODE> </CODE><TT>(</TT>r<CODE>+</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val augment : Rep.item array array -&gt; int -&gt; Rep.move *)</CODE><BR><CODE> </CODE><CODE>(* 'augment m c' redoes the line or drops the piece for c in m *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>augment<CODE> </CODE>mat<CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>row<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE><CODE>!</CODE>l<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE>mat<CODE>.</CODE><TT>(</TT><CODE>!</CODE>l<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE>.</CODE><TT>(</TT>c<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Empty<CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>decr<CODE> </CODE>l<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>l<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val conv : Graphics.status -&gt; int *)</CODE><BR><CODE> </CODE><CODE>(* convert the region where player has clicked in controlling the game *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>conv<CODE> </CODE>st<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>st<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>5</CODE><TT>)</TT><CODE> </CODE><CODE>/</CODE><CODE> </CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val wait_click : unit -&gt; Graphics.status *)</CODE><BR><CODE> </CODE><CODE>(* wait for a mouse click *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>wait_click<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.wait_next_event<CODE> </CODE><CODE>[</CODE>Graphics<CODE>.</CODE>Button_down<CODE>]</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val choiceH : Rep.game -&gt; Rep.move *)</CODE><BR><CODE> </CODE><CODE>(* give opportunity to the human player to choose a move *)</CODE><BR><CODE> </CODE><CODE>(* the function offers possible moves *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>choice<CODE> </CODE>player<CODE> </CODE><CODE> </CODE>game<CODE> </CODE><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE>not<CODE> </CODE><TT>(</TT><CODE> </CODE>List.mem<CODE> </CODE><CODE>!</CODE>c<CODE> </CODE><TT>(</TT>legal_moves<CODE> </CODE>player<CODE> </CODE>game<TT>)</TT><CODE> </CODE><TT>)</TT><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>c<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>conv<CODE> </CODE><TT>(</TT><CODE> </CODE>wait_click()<CODE> </CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>c<BR><CODE> </CODE><CODE>(* val home : unit -&gt; unit : home screen *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>home<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.open_graph<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>" "</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>width<TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"x"</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>height<TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"+50+50"</CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><TT>(</TT>height<CODE>/</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>width<CODE>/</CODE><CODE>2</CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cF;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE><CODE>"C4"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cN;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>2</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE><CODE>"by Romuald COEFFIER &amp; Mathieu DESPIERRE"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>wait_click<CODE> </CODE>()<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.clear_graph()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val end : unit -&gt; unit ,  the end of the game *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>exit<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.close_graph()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val draw_button : int -&gt; int -&gt; int -&gt; int -&gt; string -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* 'draw_button x y w h s' draws a rectangular button at coordinates *)</CODE><BR><CODE> </CODE><CODE>(* x,y with width w and height h and appearance s *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_button<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>w<CODE> </CODE>h<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cN;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE>x<CODE> </CODE>y;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE>x<CODE> </CODE><TT>(</TT>y<CODE>+</CODE>h<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE><TT>(</TT>x<CODE>+</CODE>w<TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE>+</CODE>h<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE><TT>(</TT>x<CODE>+</CODE>w<TT>)</TT><CODE> </CODE>y;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE>x<CODE> </CODE>y;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><TT>(</TT>x<CODE>+</CODE>margin<TT>)</TT><CODE> </CODE><TT>(</TT>hec<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* val draw_message : string -&gt; unit  * position message s *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_message<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cN;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE>lec<CODE> </CODE>hec;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* val erase_message : unit -&gt; unit  erase the starting position *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>erase_message<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>Graphics.white;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>height_of_game<CODE>+</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>width<CODE> </CODE>htexte<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val question : string -&gt; bool *)</CODE><BR><CODE> </CODE><CODE>(* 'question s' poses the question s, the response being obtained by *)</CODE><BR><CODE> </CODE><CODE>(*    selecting one of two buttons, 'yes' (=true) and 'no' (=false) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>question<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>attente<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>wait_click<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_y<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><TT>(</TT>yb<CODE>+</CODE>hb<TT>)</TT><TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_y<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>yb<TT>)</TT><CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>xb1<TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><TT>(</TT>xb1<CODE>+</CODE>wb<TT>)</TT><TT>)</TT><CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>true</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>xb2<TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><TT>(</TT>xb2<CODE>+</CODE>wb<TT>)</TT><TT>)</TT><CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>attente()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>attente<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_message<CODE> </CODE>s;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_button<CODE> </CODE>xb1<CODE> </CODE>yb<CODE> </CODE>wb<CODE> </CODE>hb<CODE> </CODE><CODE>"yes"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_button<CODE> </CODE>xb2<CODE> </CODE>yb<CODE> </CODE>wb<CODE> </CODE>hb<CODE> </CODE><CODE>"no"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>attente()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val q_begin : unit -&gt; bool *)</CODE><BR><CODE> </CODE><CODE>(* Ask, using function 'question', if the player wishes to start *)</CODE><BR><CODE> </CODE><CODE>(* (yes=true) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>q_begin<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Would you like to begin ?"</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>erase_message();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>b<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val q_continue : unit -&gt; bool *)</CODE><BR><CODE> </CODE><CODE>(* Ask, using function 'question', if the player wishes to play again *)</CODE><BR><CODE> </CODE><CODE>(* (yes=true) *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>q_continue<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Play again ?"</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>erase_message();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>b<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>q_player<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Is there to be a machine player?"</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>erase_message<CODE> </CODE>();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>b<BR><CODE> </CODE><CODE>(* val won : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* val lost : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* val nil : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* Three functions for these three cases *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>won<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_message<CODE> </CODE><CODE>"I won :-)"</CODE><CODE> </CODE>;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>wait_click<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<CODE> </CODE>erase_message()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lost<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_message<CODE> </CODE><CODE>"You won :-("</CODE>;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>wait_click<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<CODE> </CODE>erase_message()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>nil<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_message<CODE> </CODE><CODE>"Stalemate"</CODE><CODE> </CODE>;<CODE> </CODE>ignore<CODE> </CODE><TT>(</TT>wait_click<CODE> </CODE>()<TT>)</TT><CODE> </CODE>;<CODE> </CODE>erase_message()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* val init : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* This is called at every start of the game for the position *)</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>init<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>draw_table<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>position<CODE> </CODE>b<CODE> </CODE>c<CODE> </CODE>aj<CODE> </CODE>nj<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>b<CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_piece<CODE> </CODE><TT>(</TT>augment<CODE> </CODE>nj<CODE> </CODE>c<TT>)</TT><CODE> </CODE>c<CODE> </CODE>cA<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_piece<CODE> </CODE><TT>(</TT>augment<CODE> </CODE>nj<CODE> </CODE>c<TT>)</TT><CODE> </CODE>c<CODE> </CODE>cB<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* val drawH : int -&gt; Rep.item array array -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* Position when the human player chooses move cp in situation j *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drawH<CODE> </CODE>cp<CODE> </CODE>j<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>draw_piece<CODE> </CODE><TT>(</TT>augment<CODE> </CODE>j<CODE> </CODE>cp<TT>)</TT><CODE> </CODE>cp<CODE> </CODE>cA<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* val drawM : int -&gt; cell array array -&gt; unit*)</CODE><BR><CODE> </CODE><CODE>(* Position when the machine player chooses move cp in situation j *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>drawM<CODE> </CODE>cp<CODE> </CODE>j<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>draw_piece<CODE> </CODE><TT>(</TT>augment<CODE> </CODE>j<CODE> </CODE>cp<TT>)</TT><CODE> </CODE>cp<CODE> </CODE>cB<BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module C4_graph :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game = C4_rep.game</CODE><BR><CODE>    and move = C4_rep.move</CODE><BR><CODE>    val r : int</CODE><BR><CODE>    val ec : int</CODE><BR><CODE>    val dec : int</CODE><BR><CODE>    val cote : int</CODE><BR><CODE>    val htexte : int</CODE><BR><CODE>    val width : int</CODE><BR><CODE>    val height : int</CODE><BR><CODE>    val height_of_game : int</CODE><BR><CODE>    val hec : int</CODE><BR><CODE>    val lec : int</CODE><BR><CODE>    val margin : int</CODE><BR><CODE>    val xb1 : int</CODE><BR><CODE>    val xb2 : int</CODE><BR><CODE>    val yb : int</CODE><BR><CODE>    val wb : int</CODE><BR><CODE>    val hb : int</CODE><BR><CODE>    val t2e : int -&gt; int</CODE><BR><CODE>    val cN : Graphics.color</CODE><BR><CODE>    val cA : Graphics.color</CODE><BR><CODE>    val cB : Graphics.color</CODE><BR><CODE>    val cF : Graphics.color</CODE><BR><CODE>    val draw_table : unit -&gt; unit</CODE><BR><CODE>    val draw_piece : int -&gt; int -&gt; Graphics.color -&gt; unit</CODE><BR><CODE>    val augment : C4_rep.cell array array -&gt; int -&gt; int</CODE><BR><CODE>    val conv : Graphics.status -&gt; int</CODE><BR><CODE>    val wait_click : unit -&gt; Graphics.status</CODE><BR><CODE>    val choice : 'a -&gt; C4_rep.cell array array -&gt; int</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val draw_button : int -&gt; int -&gt; int -&gt; int -&gt; string -&gt; unit</CODE><BR><CODE>    val draw_message : string -&gt; unit</CODE><BR><CODE>    val erase_message : unit -&gt; unit</CODE><BR><CODE>    val question : string -&gt; bool</CODE><BR><CODE>    val q_begin : unit -&gt; bool</CODE><BR><CODE>    val q_continue : unit -&gt; bool</CODE><BR><CODE>    val q_player : unit -&gt; bool</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; unit</CODE><BR><CODE>    val position : bool -&gt; int -&gt; 'a -&gt; C4_rep.cell array array -&gt; unit</CODE><BR><CODE>    val drawH : int -&gt; C4_rep.cell array array -&gt; unit</CODE><BR><CODE>    val drawM : int -&gt; C4_rep.cell array array -&gt; unit</CODE><BR><CODE>  end</CODE><BR>

</PRE>

<BR>
<BR>
We may also create a new skeleton (<TT>C4_skeletonG</TT>) which
results from the application of parametric module <TT>FSkeleton</TT>.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_skeletonG<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>FSkeleton<CODE> </CODE><TT>(</TT>C4_rep<TT>)</TT><CODE> </CODE><TT>(</TT>C4_graph<TT>)</TT><CODE> </CODE><TT>(</TT>C4_eval<TT>)</TT><CODE> </CODE><TT>(</TT>FAlphabeta<CODE> </CODE><TT>(</TT>C4_rep<TT>)</TT><CODE> </CODE><TT>(</TT>C4_eval<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
Only the display parameter differs from the text
version application of 
<TT>FSkeleton</TT>. We may thereby create a principal module for
Connect Four with a graphical user interface.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>C4_mainG<CODE> </CODE><CODE>=</CODE><CODE> </CODE>FMain<TT>(</TT>C4_skeletonG<TT>)</TT><CODE> </CODE>;;<BR><CODE>module C4_mainG :</CODE><BR><CODE>  sig</CODE><BR><CODE>    val play_game : (unit -&gt; 'a) * (unit -&gt; 'b) -&gt; unit</CODE><BR><CODE>    val main : unit -&gt; unit</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
The evaluation of the expression <TT>C4_mainG.main()</TT> opens a
graphical window as in figure <A HREF="book-ora160.html#fig-p4">17.5</A> and controls the interaction
with the user.<BR>
<BR>
<A NAME="toc233"></A>
<H3> Stonehenge</H3>Stonehenge, created by Reiner Knizia, is a game involving
construction of ``ley-lines.'' The rules are simple to understand
but our interest in the game lies in its high number of possible moves. The 
rules may be found at:<BR>
<BR>


<H3> Link </H3> <HR>

<A HREF="http://www.cix.co.uk/~convivium/files/stonehen.htm">http://www.cix.co.uk/~convivium/files/stonehen.htm</A>


<HR>

<BR>
<BR>
The initial game position is represented in figure 
<A HREF="book-ora160.html#fig-stonehenge1">17.6</A>.<BR>
<BR>

<H4> Game Presentation</H4>
The purpose of the game is to win at least 8 ``ley-lines'' (clear
lines) out of the 15 available. One gains a line 
by positioning pieces (or megaliths) on gray positions
along a ley-line.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora071.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.6: Initial position of Stonehenge.</DIV><BR>

<A NAME="fig-stonehenge1"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>In turn, each player places one of his 9 pieces, numbered from
1 to 6, on one of the 18 gray internal positions. They may not place
a piece on a position that is already occupied. Each time a piece is
placed, one or several ley-lines may be won or lost.<BR>
<BR>
A ley-line is won by a player if the total of the values of his
pieces on the line is greater than the total of the pieces for the
other player. There may be empty spaces left if the opponent has no
pieces left that would allow winning the line.<BR>
<BR>
For example in figure <A HREF="book-ora160.html#fig-stonehenge2">17.7</A>, the black player starts
by placing the piece of value 3, the red player his ``2'' piece,
then the black player plays the ``6'' piece, winning a line. <BR>
<BR>
Red then plays the ``4'' piece, also winning a ley-line. This line
has not been completely filled, but red has won because there is no
way for black to overcome red's score.<BR>
<BR>
Note that the red player might just as well have played ``3''
rather than ``4,'' and still won the line. In effect, there is only
one free case for this ley-line where the strongest black piece has
a value of 5, and so black cannot beat red for this particular line.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora072.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.7: Position after 4 moves.</DIV><BR>

<A NAME="fig-stonehenge2"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>In the case where the scores are equal across a full line, whoever
placed the last piece <EM>without</EM> having beaten his adversary's
score, loses the line. Figure <A HREF="book-ora160.html#fig-stonehenge3">17.8</A> demonstrates such
a situation.<BR>
<BR>
The last red move is piece ``4''. On the full line where the ``4''
is placed, the scores are equal. Since red was the last player to
have placed a piece, but did not beat his adversary, red loses the line,
as indicated by a black block.<BR>
<BR>
We may observe that the function <TT>play</TT> fills the role of
arbitrating and accounting for these subtleties in the placement of
lines.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<IMG SRC="book-ora073.gif">
</DIV>
<BR>
<DIV ALIGN=center>Figure 17.8: Position after 6 moves.</DIV><BR>

<A NAME="fig-stonehenge3"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>There can never be a tie in this game. There are 15 lines, each of
which will be accounted for at some point in the game, at which point
one of the players will have won at least 8 lines.<BR>
<BR>

<H4> Search Complexity</H4>Before completely implementing a new game, it is important to estimate
the number of legal moves between two moves in a game, as well as the
number of possible moves for each side. These values may be used to
estimate a reasonable maximum depth for the minimax-<FONT FACE=symbol>a</FONT><FONT FACE=symbol>b</FONT>
algorithm.<BR>
<BR>
In the game Stonehenge, the number of moves for each side is initially
based on the number of pieces for the two players, that is, 18. The
number of possible moves diminishes as the game progresses. At the
first move, the player has 6 different pieces and 18 positions free.
At the second move, the second player has 6 different pieces, and 17
positions in which they may be placed (102 legal moves). Moving from
a depth of 2 to 4 for the initial moves of the game results in the
number of choices going from about 10<SUP><FONT SIZE=2>4</FONT></SUP> to about 10<SUP><FONT SIZE=2>8</FONT></SUP>.<BR>
<BR>
On the other hand, near the end of the game, in the final 8 moves, the
complexity is greatly reduced. If we take a pessimistic calculation
(where all pieces are different), we obtain about 23 million
possibilities:<BR>
<BR>
<DIV ALIGN=center>
 4*8 * 4*7 * 3*6 * 3*5 * 2*4 * 2*3 * 1*2 * 1*1 = 23224320
</DIV><BR>
It might seem appropriate to calculate with a depth of around 2 for
the initial set of moves. This may depend on the evaluation function,
and on its ability to evaluate the positions at the start of the
game, when there are few pieces in place. On the other hand, near the
end of the game, the depth may readily be increased to around 4 or 6,
but this would probably be too late a point to recover from a weak
position.<BR>
<BR>

<H4> Implementation</H4>We jump straight into describing the game representation and
arbitration so that we may concentrate on the evaluation function.<BR>
<BR>
The implementation of this game follows the architecture used for 
Connect Four, described in figure <A HREF="book-ora160.html#fig-orgjeux">17.4</A>. The two
principal difficulties will be to follow the game rules for the
placement of pieces, and the evaluation function, which must be able to
evaluate positions as quickly as possible while remaining useful.<BR>
<BR>

<H5> Game Representation.</H5>
There are four notable data structures in this game:
<UL>
<LI>
 the pieces of the players (type <I>piece</I>),

<LI> the positions (type <I>placement</I>),

<LI> the 15 ley-lines,

<LI> the 18 locations where pieces may be placed.
</UL>We provide a unique number for each location:
<PRE>
             1---2
            / \ / \
           3---4---5
          / \ / \ / \
         6---7---8---9
        / \ / \ / \ / \
       10--11--12--13--14
        \ / \ / \ / \ /
         15--16--17--18 
</PRE>Each location participates in 3 ley-lines. We also number each
ley-line. This description may be found in the declaration of the
list <I>lines</I>, which is converted to a vector
(<TT>vector_l</TT>). A location is either empty, or contains a
piece that has been placed, and the piece's possessor. We also store, 
for each location, the number of the lines that pass through it.
This table is calculated by 
<TT>lines_per_case</TT> and is named
<TT>num_line_per_case</TT>.<BR>
<BR>
The game is represented by the vector of 18 cases, the vector of 15
ley-lines either won or not, and the lists of pieces left for
the two players. The function <TT>game_start</TT> creates these four
elements.<BR>
<BR>
The calculation of a player's legal moves resolves into a Cartesian
product of the pieces available against the free positions. Various
utility functions allow counting the score of a player on a line,
calculating the number of empty locations on a line, and verifying
if a line has already been won. We only need to implement 
<TT>play</TT> which plays a move and decides which pieces to
place. We write this function at the end of the listing of module
<TT>Stone_rep</TT>.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>Stone_rep<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>player<CODE> </CODE><CODE>=</CODE><CODE> </CODE>bool<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>piece<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>P<CODE> </CODE><B>of</B><CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>int_of_piece<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>P<CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>placement<CODE> </CODE><CODE>=</CODE><CODE> </CODE>None<CODE> </CODE><CODE>|</CODE><CODE> </CODE>M<CODE> </CODE><B>of</B><CODE> </CODE>player<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>case<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Empty<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Occup<CODE> </CODE><B>of</B><CODE> </CODE>player<CODE>*</CODE>piece<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>value_on_case<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Empty<CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Occup<CODE> </CODE><TT>(</TT>j<CODE>,</CODE><CODE> </CODE>x<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>int_of_piece<CODE> </CODE>x<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>J<CODE> </CODE><B>of</B><CODE> </CODE>case<CODE> </CODE>array<CODE> </CODE><CODE>*</CODE><CODE> </CODE>placement<CODE> </CODE>array<CODE> </CODE><CODE>*</CODE><CODE> </CODE>piece<CODE> </CODE>list<CODE> </CODE><CODE>*</CODE><CODE> </CODE>piece<CODE> </CODE>list<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>int<CODE> </CODE><CODE>*</CODE><CODE> </CODE>piece<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lines<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE>0</CODE>;<CODE>1</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>5</CODE>;<CODE> </CODE><CODE>6</CODE>;<CODE> </CODE><CODE>7</CODE>;<CODE> </CODE><CODE>8</CODE>;<CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>9</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>3</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>1</CODE><CODE>4</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>5</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>6</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE>]</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>5</CODE>;<CODE> </CODE><CODE>9</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>6</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>4</CODE>;<CODE> </CODE><CODE>7</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>5</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>8</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>6</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>1</CODE><CODE>3</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE>]</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE>9</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>5</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>5</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>6</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>6</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>7</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE>]</CODE>;<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>4</CODE>;<CODE> </CODE><CODE>8</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>3</CODE><CODE>]</CODE><CODE> </CODE><CODE> </CODE><CODE>]</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>vector_l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.of_list<CODE> </CODE>lines<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lines_per_case<CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>Array.length<CODE> </CODE>v<CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.create<CODE> </CODE><CODE>1</CODE><CODE>8</CODE><CODE> </CODE><CODE>[||]</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE> </CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>w<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.create<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>j<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE>t<CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>do</B><CODE> </CODE><B>if</B><CODE> </CODE>List.mem<CODE> </CODE>i<CODE> </CODE>v<CODE>.</CODE><TT>(</TT>j<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT>w<CODE>.</CODE><TT>(</TT><CODE>!</CODE>p<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>j;<CODE> </CODE>incr<CODE> </CODE>p<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>r<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>w<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>r<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>num_line_per_case<CODE> </CODE><CODE>=</CODE><CODE> </CODE>lines_per_case<CODE> </CODE>vector_l<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>lines_of_i<CODE> </CODE>i<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.filter<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>t<CODE> </CODE>-&gt;<CODE> </CODE>List.mem<CODE> </CODE>i<CODE> </CODE>t<TT>)</TT><CODE> </CODE>l<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lines_of_cases<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.create<CODE> </CODE><CODE>1</CODE><CODE>8</CODE><CODE> </CODE>l<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>a<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>lines_of_i<CODE> </CODE>i<CODE> </CODE>l<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<CODE> </CODE>a<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>ldc<CODE> </CODE><CODE>=</CODE><CODE> </CODE>lines_of_cases<CODE> </CODE>lines<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>game_start<CODE> </CODE>()<CODE>=</CODE><CODE> </CODE><B>let</B><CODE> </CODE>lp<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE><CODE>6</CODE>;<CODE> </CODE><CODE>5</CODE>;<CODE> </CODE><CODE>4</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>1</CODE>;<CODE> </CODE><CODE>1</CODE><CODE>]</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>J<CODE> </CODE><TT>(</TT><CODE> </CODE>Array.create<CODE> </CODE><CODE>1</CODE><CODE>8</CODE><CODE> </CODE>Empty<CODE>,</CODE><CODE> </CODE>Array.create<CODE> </CODE><CODE>1</CODE><CODE>5</CODE><CODE> </CODE>None<CODE>,</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.map<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>P<CODE> </CODE>x<TT>)</TT><CODE> </CODE>lp<CODE>,</CODE><CODE> </CODE>List.map<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>P<CODE> </CODE>x<TT>)</TT><CODE> </CODE>lp<CODE> </CODE><TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>unicity<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>[]<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>h::t<CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>List.mem<CODE> </CODE>h<CODE> </CODE>t<CODE> </CODE><B>then</B><CODE> </CODE>unicity<CODE> </CODE>t<CODE> </CODE><B>else</B><CODE> </CODE>h::<CODE> </CODE><TT>(</TT>unicity<CODE> </CODE>t<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>legal_moves<CODE> </CODE>player<CODE> </CODE><TT>(</TT>J<CODE> </CODE><TT>(</TT>ca<CODE>,</CODE><CODE> </CODE>m<CODE>,</CODE><CODE> </CODE>r1<CODE>,</CODE><CODE> </CODE>r2<TT>)</TT><TT>)</TT><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>r1<CODE> </CODE><B>else</B><CODE> </CODE>r2<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<CODE> </CODE><B>then</B><CODE> </CODE>[]<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>[]<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>value_on_case<CODE> </CODE>ca<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE>l<CODE>:=</CODE><CODE> </CODE>i::<CODE> </CODE><CODE>!</CODE>l<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.map<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x-&gt;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.map<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>y-&gt;<CODE> </CODE>x<CODE>,</CODE>y<TT>)</TT><CODE> </CODE><TT>(</TT>List.rev<TT>(</TT>unicity<CODE> </CODE>r<TT>)</TT><TT>)</TT><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>!</CODE>l<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.flatten<CODE> </CODE>l2<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>copy_board<CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.copy<CODE> </CODE>p<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><CODE> </CODE>carn_copy<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.copy<CODE> </CODE>m<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>play_piece<CODE> </CODE>stone<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>[]<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>x::q<CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>x<CODE>=</CODE>stone<CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE>q<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>x::<TT>(</TT>play_piece<CODE> </CODE>stone<CODE> </CODE>q<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>count_case<CODE> </CODE>player<CODE> </CODE>case<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>case<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Empty<CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Occup<CODE> </CODE><TT>(</TT>j<CODE>,</CODE>p<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>j<CODE> </CODE><CODE>=</CODE><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT>int_of_piece<CODE> </CODE>p<TT>)</TT><CODE> </CODE><B>else</B><CODE> </CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>count_line<CODE> </CODE>player<CODE> </CODE>line<CODE> </CODE>pos<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.fold_left<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE> </CODE>count_case<CODE> </CODE>player<CODE> </CODE>pos<CODE>.</CODE><TT>(</TT>y<TT>)</TT><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE>line<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>count_max<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>n<CODE>&gt;</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>int_of_piece<CODE> </CODE>t<TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE>count_max<CODE> </CODE><TT>(</TT>n<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>q<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>nbr_cases_free<CODE> </CODE>ca<CODE> </CODE><CODE> </CODE>l<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<CODE> </CODE><B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ca<CODE>.</CODE><TT>(</TT>t<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>c<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Empty<CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>nbr_cases_free<CODE> </CODE>ca<CODE> </CODE>q<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>nbr_cases_free<CODE> </CODE>ca<CODE> </CODE>q<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>a_placement<CODE> </CODE>i<CODE> </CODE>ma<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>ma<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>None<CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>true</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>which_placement<CODE> </CODE>i<CODE> </CODE>ma<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>ma<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>None<CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"which_placement"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>M<CODE> </CODE>j<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>j<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_filled<CODE> </CODE>l<CODE> </CODE>ca<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>nbr_cases_free<CODE> </CODE>ca<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* function play : arbitrates the game *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>play<CODE> </CODE>player<CODE> </CODE>move<CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><TT>(</TT>c<CODE>,</CODE><CODE> </CODE>i<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>move<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>J<CODE> </CODE><TT>(</TT>p<CODE>,</CODE><CODE> </CODE>m<CODE>,</CODE><CODE> </CODE>r1<CODE>,</CODE><CODE> </CODE>r2<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>game<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>nr1<CODE>,</CODE>nr2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>play_piece<CODE> </CODE>i<CODE> </CODE>r1<CODE>,</CODE>r2<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>r1<CODE>,</CODE><CODE> </CODE><CODE> </CODE>play_piece<CODE> </CODE>i<CODE> </CODE>r2<CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>np<CODE> </CODE><CODE>=</CODE><CODE> </CODE>copy_board<CODE> </CODE>p<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>nm<CODE> </CODE><CODE>=</CODE><CODE> </CODE>carn_copy<CODE> </CODE>m<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>np<CODE>.</CODE><TT>(</TT>c<TT>)</TT><CODE>&lt;-</CODE>Occup<TT>(</TT>player<CODE>,</CODE>i<TT>)</TT>;<CODE> </CODE><CODE> </CODE><CODE>(* on play le move *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lines_of_the_case<CODE> </CODE><CODE>=</CODE><CODE> </CODE>num_line_per_case<CODE>.</CODE><TT>(</TT>c<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* calculation of the placements of the three lines *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>k<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>2</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>lines_of_the_case<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>not<CODE> </CODE><TT>(</TT>a_placement<CODE> </CODE>l<CODE> </CODE>nm<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>is_filled<CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE> </CODE>np<CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>count_line<CODE> </CODE>player<CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE> </CODE>np<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>c2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>count_line<CODE> </CODE><TT>(</TT>not<CODE> </CODE>player<TT>)</TT><CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE> </CODE>np<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>c1<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>c2<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>M<CODE> </CODE>player<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><B>if</B><CODE> </CODE>c2<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>c1<CODE> </CODE><B>then</B><CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>M<CODE> </CODE><TT>(</TT>not<CODE> </CODE>player<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>l<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>M<CODE> </CODE><TT>(</TT>not<CODE> </CODE>player<CODE> </CODE><TT>)</TT><TT>)</TT><TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* calculation of other placements *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>k<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>not<CODE> </CODE><TT>(</TT>a_placement<CODE> </CODE>k<CODE> </CODE>nm<CODE> </CODE><TT>)</TT><CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>is_filled<CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE>np<CODE> </CODE><B>then</B><CODE> </CODE>failwith<CODE> </CODE><CODE>"player"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>count_line<CODE> </CODE>player<CODE> </CODE><CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE>np<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>c2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>count_line<CODE> </CODE><TT>(</TT>not<CODE> </CODE>player<TT>)</TT><CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE>np<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cases_free<CODE> </CODE><CODE>=</CODE><CODE> </CODE>nbr_cases_free<CODE> </CODE>np<CODE> </CODE>vector_l<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>max1<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>count_max<CODE> </CODE>cases_free<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>nr1<CODE> </CODE><B>else</B><CODE> </CODE>nr2<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>max2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>count_max<CODE> </CODE>cases_free<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>nr2<CODE> </CODE><B>else</B><CODE> </CODE>nr1<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>c1<CODE> </CODE><CODE>&gt;=</CODE><CODE> </CODE>c2<CODE> </CODE><CODE>+</CODE><CODE> </CODE>max2<CODE> </CODE><B>then</B><CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>M<CODE> </CODE>player<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><B>if</B><CODE> </CODE>c2<CODE> </CODE><CODE>&gt;=</CODE><CODE> </CODE>c1<CODE> </CODE><CODE>+</CODE><CODE> </CODE>max1<CODE> </CODE><B>then</B><CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>k<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>M<CODE> </CODE><TT>(</TT>not<CODE> </CODE>player<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>J<TT>(</TT>np<CODE>,</CODE>nm<CODE>,</CODE>nr1<CODE>,</CODE>nr2<TT>)</TT><BR><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>module Stone_rep :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type player = bool</CODE><BR><CODE>    and piece = | P of int</CODE><BR><CODE>    val int_of_piece : piece -&gt; int</CODE><BR><CODE>    type placement = | None | M of player</CODE><BR><CODE>    and case = | Empty | Occup of player * piece</CODE><BR><CODE>    val value_on_case : case -&gt; int</CODE><BR><CODE>    type game = | J of case array * placement array * piece list * piece list</CODE><BR><CODE>    and move = int * piece</CODE><BR><CODE>    val lines : int list list</CODE><BR><CODE>    val vector_l : int list array</CODE><BR><CODE>    val lines_per_case : int list array -&gt; int array array</CODE><BR><CODE>    val num_line_per_case : int array array</CODE><BR><CODE>    val lines_of_i : 'a -&gt; 'a list list -&gt; 'a list list</CODE><BR><CODE>    val lines_of_cases : int list list -&gt; int list list array</CODE><BR><CODE>    val ldc : int list list array</CODE><BR><CODE>    val game_start : unit -&gt; game</CODE><BR><CODE>    val unicity : 'a list -&gt; 'a list</CODE><BR><CODE>    val legal_moves : bool -&gt; game -&gt; (int * piece) list</CODE><BR><CODE>    val copy_board : 'a array -&gt; 'a array</CODE><BR><CODE>    val carn_copy : 'a array -&gt; 'a array</CODE><BR><CODE>    val play_piece : 'a -&gt; 'a list -&gt; 'a list</CODE><BR><CODE>    val count_case : player -&gt; case -&gt; int</CODE><BR><CODE>    val count_line : player -&gt; int list -&gt; case array -&gt; int</CODE><BR><CODE>    val count_max : int -&gt; piece list -&gt; int</CODE><BR><CODE>    val nbr_cases_free : case array -&gt; int list -&gt; int</CODE><BR><CODE>    val a_placement : int -&gt; placement array -&gt; bool</CODE><BR><CODE>    val which_placement : int -&gt; placement array -&gt; player</CODE><BR><CODE>    val is_filled : int list -&gt; case array -&gt; bool</CODE><BR><CODE>    val play : player -&gt; int * piece -&gt; game -&gt; game</CODE><BR><CODE>  end</CODE><BR>

</PRE>

<BR>
<BR>
The function <TT>play</TT> decomposes into three stages:
<OL type=1>
<LI> Copying the game position and placing a move onto this
position;<BR>
<BR>

<LI> Determination of the placement of a piece on one of the three
lines of the case played;<BR>
<BR>

<LI> Treatment of the other ley-lines.</OL>
The second stage verifies that, of the three lines passing through
the position of the move, none has already been won, and then checks if
they are able to be won. In the latter case, it counts scores for
each player and determines which strictly has the greatest score, and
attributes the line to the appropriate player. In case of equality,
the line goes to the most recent player's adversary. In
effect, there are no lines with just one case. A filled line has at
least two pieces. Thus if the player which just played has just
matched the score of his adversary, he cannot expect to win the line
which then goes to his adversary. If the line is not filled, it will
be analyzed by ``stage 3.''<BR>
<BR>
The third stage verifies for each line not yet 
attributed that it is not filled, and then checks if a player cannot be
beaten by his opponent. In this case, the line is immediately given
to the opponent. To perform this test, it is necessary to calculate
the maximum total potential score of a player on the line (that is, by
using his best pieces). If the line is still under dispute, nothing
more is done.<BR>
<BR>

<H5> Evaluation.</H5>
The evaluation function must remain simple due to the large number of
cases to deal with near the beginning of the game. The idea is not to
excessively simplify the game by immediately playing the strongest
pieces which would then leave the remainder of the game open for the
adversary to play his strong pieces.<BR>
<BR>
We will use two criteria: the number of lines won and an estimate of the
potential of future moves by calculating the value of the remaining
pieces. We may use the following formula for player 1:<BR>
<BR>
<DIV ALIGN=center> 
<I>score</I> &nbsp; = &nbsp; 50 * (<I>c</I><SUB><FONT SIZE=2>1</FONT></SUB> - <I>c</I><SUB><FONT SIZE=2>2</FONT></SUB>) + 10 * (<I>pr</I><SUB><FONT SIZE=2>1</FONT></SUB> - <I>pr</I><SUB><FONT SIZE=2>2</FONT></SUB>)
</DIV><BR>
where <I>c</I><SUB><FONT SIZE=2><I>i</I></FONT></SUB> is the number of lines won, and <I>pr</I><SUB><FONT SIZE=2><I>i</I></FONT></SUB> is the sum of the
pieces remaining for player <I>i</I>.<BR>
<BR>
The formula returns a positive result if the differences between won
lines (<I>c</I><SUB><FONT SIZE=2>1</FONT></SUB> - <I>c</I><SUB><FONT SIZE=2>2</FONT></SUB>) and the potentials (<I>pr</I><SUB><FONT SIZE=2>1</FONT></SUB> - <I>pr</I><SUB><FONT SIZE=2>2</FONT></SUB>) turn to the
advantage of player 1. We may see thus that a placement of piece 6 is
not appropriate unless it provides a win of at least 2 lines. The
gain of one line provides 50, while using the ``6'' piece costs 10
� 6 points, so we would thus prefer to play ``1'' which results
in the same score, namely a loss of 10 points.<BR>
<BR>


<PRE>
# <B>module</B><CODE> </CODE>Stone_eval<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>open</B><CODE> </CODE>Stone_rep<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Stone_rep.game<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>exception</B><CODE> </CODE>Done<CODE> </CODE><B>of</B><CODE> </CODE>bool<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>moreI<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE><B>and</B><CODE> </CODE><CODE> </CODE>lessI<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>nbr_lines_won<CODE> </CODE><CODE> </CODE><TT>(</TT>J<TT>(</TT>ca<CODE>,</CODE><CODE> </CODE>m<CODE>,</CODE>r1<CODE>,</CODE>r2<TT>)</TT><TT>)</TT><CODE> </CODE><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c1<CODE>,</CODE>c2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE>,</CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>a_placement<CODE> </CODE>i<CODE> </CODE>m<CODE> </CODE><B>then</B><CODE> </CODE><B>if</B><CODE> </CODE>which_placement<CODE> </CODE>i<CODE> </CODE>m<CODE> </CODE><B>then</B><CODE> </CODE>incr<CODE> </CODE>c1<CODE> </CODE><B>else</B><CODE> </CODE>incr<CODE> </CODE>c2<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>c1<CODE>,!</CODE>c2<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>nbr_points_remaining<CODE> </CODE>lig<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>lig<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>int_of_piece<CODE> </CODE>t<TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE>nbr_points_remaining<CODE> </CODE>q<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>evaluate<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><TT>(</TT>J<CODE> </CODE><TT>(</TT>ca<CODE>,</CODE>ma<CODE>,</CODE>r1<CODE>,</CODE>r2<TT>)</TT><TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>game<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c1<CODE>,</CODE>c2<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>nbr_lines_won<CODE> </CODE><CODE> </CODE>game<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>pr1<CODE>,</CODE>pr2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>nbr_points_remaining<CODE> </CODE>r1<CODE>,</CODE><CODE> </CODE>nbr_points_remaining<CODE> </CODE>r2<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>player<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>true</B><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>c1<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>7</CODE><CODE> </CODE><B>then</B><CODE> </CODE>moreI<CODE> </CODE><B>else</B><CODE> </CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>c1<CODE> </CODE><CODE>-</CODE><CODE> </CODE>c2<TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>pr1<CODE> </CODE><CODE>-</CODE><CODE> </CODE>pr2<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><B>false</B><CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>c2<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>7</CODE><CODE> </CODE><B>then</B><CODE> </CODE>lessI<CODE> </CODE><B>else</B><CODE> </CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>c1<CODE> </CODE><CODE>-</CODE><CODE> </CODE>c2<TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>pr1<CODE> </CODE><CODE>-</CODE><CODE> </CODE>pr2<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_leaf<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>evaluate<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>moreI<CODE> </CODE><B>or</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>lessI<CODE> </CODE><B>or</B><CODE> </CODE>legal_moves<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>is_stable<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>true</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>state<CODE> </CODE><CODE>=</CODE><CODE> </CODE>G<CODE> </CODE><CODE>|</CODE><CODE> </CODE>P<CODE> </CODE><CODE>|</CODE><CODE> </CODE>N<CODE> </CODE><CODE>|</CODE><CODE> </CODE>C<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>state_of<CODE> </CODE>player<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>evaluate<CODE> </CODE>player<CODE> </CODE>m<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>moreI<CODE> </CODE><B>then</B><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>G<CODE> </CODE><B>else</B><CODE> </CODE>P<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>lessI<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>P<CODE> </CODE><B>else</B><CODE> </CODE>G<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>legal_moves<CODE> </CODE>player<CODE> </CODE><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<CODE> </CODE><B>then</B><CODE> </CODE><CODE> </CODE>N<CODE> </CODE><B>else</B><CODE> </CODE>C<BR><CODE> </CODE><B>end</B>;;<BR><CODE>module Stone_eval :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type game = Stone_rep.game</CODE><BR><CODE>    exception Done of bool</CODE><BR><CODE>    val moreI : int</CODE><BR><CODE>    val lessI : int</CODE><BR><CODE>    val nbr_lines_won : Stone_rep.game -&gt; int * int</CODE><BR><CODE>    val nbr_points_remaining : Stone_rep.piece list -&gt; int</CODE><BR><CODE>    val evaluate : bool -&gt; Stone_rep.game -&gt; int</CODE><BR><CODE>    val is_leaf : bool -&gt; Stone_rep.game -&gt; bool</CODE><BR><CODE>    val is_stable : 'a -&gt; 'b -&gt; bool</CODE><BR><CODE>    type state = | G | P | N | C</CODE><BR><CODE>    val state_of : bool -&gt; Stone_rep.game -&gt; state</CODE><BR><CODE>  end</CODE><BR><BR># <B>module</B><CODE> </CODE>Stone_graph<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>struct</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>open</B><CODE> </CODE>Stone_rep<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>piece<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Stone_rep.piece<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>placement<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Stone_rep.placement<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>case<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Stone_rep.case<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Stone_rep.game<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>type</B><CODE> </CODE>move<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Stone_rep.move<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* brightness for a piece *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>brightness<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* the colors  *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cBlack<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.black<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cRed<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.rgb<CODE> </CODE><CODE>1</CODE><CODE>6</CODE><CODE>5</CODE><CODE> </CODE><CODE>4</CODE><CODE>3</CODE><CODE> </CODE><CODE>2</CODE><CODE>4</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cYellow<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.yellow<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cGreen<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.rgb<CODE> </CODE><CODE>3</CODE><CODE>1</CODE><CODE> </CODE><CODE>1</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>3</CODE><CODE>3</CODE><CODE> </CODE><CODE>(*Graphics.green*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cWhite<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.white<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cGray<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.rgb<CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE>8</CODE><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE>8</CODE><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE>8</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cBlue<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.rgb<CODE> </CODE><CODE>1</CODE><CODE>9</CODE><CODE>6</CODE><CODE> </CODE><CODE>1</CODE><CODE>3</CODE><CODE>9</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><CODE> </CODE><CODE>(*Graphics.blue*)</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* width and height *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>width<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>6</CODE><CODE>0</CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>height<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>5</CODE><CODE>0</CODE><CODE>0</CODE><BR><CODE> </CODE><CODE>(* the border at the top of the screen from which drawing begins *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>top_offset<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* height of foundaries *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>bounds<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>5</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* the size of the border on the left side of the virtual table *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>virtual_table_xoffset<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE>5</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* left shift for the black pieces *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>choice_black_offset<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>4</CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* left shift for the red pieces *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>choice_red_offset<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>5</CODE><CODE>6</CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* height of a case for the virtual table *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>virtual_case_size<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>6</CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* corresp : int*int -&gt; int*int  *)</CODE><BR><CODE> </CODE><CODE>(* establishes a correspondence between a location in the matrix *)</CODE><BR><CODE> </CODE><CODE>(* and a position on the virtual table servant for drawing *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>corresp<CODE> </CODE>cp<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>cp<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>6</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>6</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>7</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>6</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>8</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>9</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>1</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>3</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>5</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>6</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>6</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>corresp2<CODE> </CODE><TT>(</TT><TT>(</TT>x<CODE>,</CODE>y<TT>)</TT><CODE> </CODE><B>as</B><CODE> </CODE>cp<TT>)</TT><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>cp<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>2</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>4</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>5</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>6</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>7</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>8</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>9</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>2</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>3</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>4</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>5</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>6</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>7</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>x<CODE>,</CODE>y<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><CODE>"Err "</CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_int<CODE> </CODE>x;print_string<CODE> </CODE><CODE>" "</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_int<CODE> </CODE>y;<CODE> </CODE>print_newline()<CODE> </CODE>;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>col<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>5</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lig<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>5</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_background : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draw the screen background  *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_background<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.clear_graph()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlue<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE>bounds<CODE> </CODE>bounds<CODE> </CODE>width<CODE> </CODE><TT>(</TT>height<CODE>-</CODE>top_offset<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_places : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draw the pieces at the start of the game *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_places<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>7</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cp<CODE> </CODE><CODE>=</CODE><CODE> </CODE>corresp<CODE> </CODE>l<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>cp<CODE> </CODE><CODE>&lt;&gt;</CODE><CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>begin</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlack<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_circle<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>cp<TT>)</TT><CODE>*</CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>cp<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>brightness<CODE>+</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cGray<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_circle<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>cp<TT>)</TT><CODE>*</CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>cp<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>brightness<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_force_lines : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draws ley-lines  *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>draw_force_lines<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cYellow<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lst<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE><TT>(</TT><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>6</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT><CODE>-</CODE><CODE>1</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>6</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT><CODE>1</CODE><CODE>0</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE> </CODE><CODE>5</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT>;<CODE> </CODE><TT>(</TT><TT>(</TT><CODE>1</CODE><CODE>0</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><CODE>,</CODE><TT>(</TT><CODE>6</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><CODE>]</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>lines<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>h::t<CODE> </CODE>-&gt;<CODE> </CODE><B>let</B><CODE> </CODE>deb<CODE> </CODE><CODE>=</CODE><CODE> </CODE>fst<CODE> </CODE>h<CODE> </CODE><B>and</B><CODE> </CODE>complete<CODE> </CODE><CODE>=</CODE><CODE> </CODE>snd<CODE> </CODE>h<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>deb<TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>deb<TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE> </CODE><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>complete<TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>complete<TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE> </CODE><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>lines<CODE> </CODE>t<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>lines<CODE> </CODE>lst<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_final_places : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draws final cases for each ley-line *)</CODE><BR><CODE> </CODE><CODE>(* coordinates represent in the virtual array</CODE><BR><CODE>   used for positioning *)</CODE><BR><CODE> </CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_final_places<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lst<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>0</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>0</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT>;<CODE> </CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><CODE>]</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>final<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>h::t<CODE> </CODE>-&gt;<CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlack<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_circle<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>h<TT>)</TT><CODE>*</CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>h<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>brightness<CODE>+</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cGreen<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_circle<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>h<TT>)</TT><CODE>*</CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>h<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>brightness<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>final<CODE> </CODE>t<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>final<CODE> </CODE>lst<BR><CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_table : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draws the whole game  *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_table<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cYellow<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_background<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_line_width<CODE> </CODE><CODE>5</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_force_lines<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_line_width<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_places<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_final_places<CODE> </CODE>();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_line_width<CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* move -&gt; couleur -&gt; unit  *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_piece<CODE> </CODE><CODE> </CODE>player<CODE> </CODE><CODE> </CODE><TT>(</TT>n_case<CODE>,</CODE>P<CODE> </CODE>cp<TT>)</TT><CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>(*   (n_caOccup(c,v),cp) col =*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>cBlack<CODE> </CODE><B>else</B><CODE> </CODE>cRed<TT>)</TT>;<CODE> </CODE><CODE>(*col;*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>co<CODE> </CODE><CODE>=</CODE><CODE> </CODE>corresp<CODE> </CODE>n_case<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>co<TT>)</TT><CODE>*</CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE>5</CODE><TT>)</TT><CODE> </CODE><B>and</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>co<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>-</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_circle<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>brightness<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cWhite<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><TT>(</TT>x<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>dummy<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>cp<TT>)</TT><CODE> </CODE><CODE>(*;*)</CODE><BR><CODE> </CODE><CODE>(*    print_string "---";print_int n_case; print_string " "; print_int cp ;print_newline() *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE>(* conv : Graphics.status -&gt; int  *)</CODE><BR><CODE> </CODE><CODE>(* convert a mouse click into a position on a virtual table permitting *)</CODE><BR><CODE> </CODE><CODE>(* its drawing *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>conv<CODE> </CODE>st<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>xx<CODE> </CODE><CODE>=</CODE><CODE> </CODE>st<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><B>and</B><CODE> </CODE>yy<CODE> </CODE><CODE>=</CODE><CODE> </CODE>st<CODE>.</CODE>Graphics.mouse_y<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>yy<CODE>+</CODE><CODE>1</CODE><CODE>0</CODE><TT>)</TT><CODE>/</CODE>virtual_case_size<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>6</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>dec<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>y<CODE>/</CODE><CODE>2</CODE><TT>)</TT><CODE>*</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><CODE>6</CODE><CODE>0</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>4</CODE><CODE>0</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>offset<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><CODE>*</CODE>y<TT>)</TT><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>-</CODE><CODE>2</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>-</CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>-</CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>-</CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>xx<CODE>+</CODE>dec<TT>)</TT><CODE>/</CODE>virtual_case_size<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>offset<CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><CODE>*</CODE>y<CODE>,</CODE><CODE> </CODE>x<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* line_number_to_aff : int -&gt; int*int *)</CODE><BR><CODE> </CODE><CODE>(* convert a line number into a polition on the virtual table serving *)</CODE><BR><CODE> </CODE><CODE>(* for drawing *)</CODE><BR><CODE> </CODE><CODE>(* the coordinate returned corresponds to the final case for the line *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>line_number_to_aff<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>n<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><CODE>,</CODE><CODE>4</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>6</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>0</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>7</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>8</CODE><CODE>,</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>8</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>9</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>0</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>1</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>5</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>7</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>3</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>9</CODE><CODE>,</CODE><CODE>6</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>0</CODE><CODE>,</CODE><CODE>5</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"line"</CODE><CODE> </CODE><CODE>(*raise Rep.Out_of_bounds*)</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_lines_won : game -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* position a marker indicating the player which has taken the line *)</CODE><BR><CODE> </CODE><CODE>(* this is done for all lines *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE><CODE> </CODE>drawb<CODE> </CODE><CODE> </CODE>l<CODE> </CODE><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>None<CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"draw"</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>M<CODE> </CODE>j<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>let</B><CODE> </CODE>pos<CODE> </CODE><CODE>=</CODE><CODE> </CODE>line_number_to_aff<CODE> </CODE>i<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE>(*                print_string "''''";</CODE><BR><CODE>   print_int i; </CODE><BR><CODE>   print_string "---";</CODE><BR><CODE>   Printf.printf "%d,%d\n" (fst pos) (snd pos);</CODE><BR><CODE>*)</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>j<CODE> </CODE><B>then</B><CODE> </CODE>cBlack<CODE> </CODE><B>else</B><CODE> </CODE>cRed<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE><TT>(</TT><TT>(</TT>fst<CODE> </CODE>pos<TT>)</TT><CODE>*</CODE><CODE>3</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>virtual_table_xoffset<CODE>-</CODE>bounds<TT>)</TT><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>snd<CODE> </CODE>pos<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>5</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>-</CODE><CODE>6</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>2</CODE><CODE>0</CODE><CODE> </CODE><CODE>4</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_lines_won<CODE> </CODE>om<CODE> </CODE>nm<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>om<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><CODE>&lt;&gt;</CODE><CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE>drawb<CODE> </CODE>nm<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE>i<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><BR><CODE> </CODE><CODE>(*********************</CODE><BR><CODE>   let black_lines = Rep.lines_won_by_player mat Rep.Noir and</CODE><BR><CODE>   red_lines = Rep.lines_won_by_player mat Rep.Rouge </CODE><BR><CODE>   in</CODE><BR><CODE>   print_string "black : "; print_int (Rep.list_size black_lines);</CODE><BR><CODE>   print_newline () ;</CODE><BR><CODE>   print_string "red : "; print_int (Rep.list_size red_lines);</CODE><BR><CODE>   print_newline() ;   </CODE><BR><BR><CODE>   let rec draw l col =</CODE><BR><CODE>   match l with</CODE><BR><CODE>   [] -&gt; ()</CODE><BR><CODE>   | h::t -&gt; let pos = line_number_to_aff h in</CODE><BR><CODE>   Graphics.set_color col ;</CODE><BR><CODE>   Graphics.fill_rect ((fst pos)*30 + virtual_table_xoffset-bounds)</CODE><BR><CODE>   (height - ((snd pos)*55 + 25)-60) 20 40 ;</CODE><BR><CODE>   draw t col</CODE><BR><CODE>   in draw black_lines cBlack ;</CODE><BR><CODE>   draw red_lines cRed</CODE><BR><CODE>   ***************************************************)</CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_poss : item list -&gt; int -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draw the pieces available for a player based on a list *)</CODE><BR><CODE> </CODE><CODE>(* the parameter "off" indicates the position at which to place the list *)</CODE><CODE> </CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_poss<CODE> </CODE>player<CODE> </CODE>lst<CODE> </CODE>off<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>draw<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>v::t<CODE> </CODE>-&gt;<CODE> </CODE><B>if</B><CODE> </CODE>player<CODE> </CODE><CODE> </CODE><B>then</B><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlack<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>Graphics.set_color<CODE> </CODE>cRed;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>off<CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE>+</CODE><TT>(</TT><CODE>!</CODE>c<TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_circle<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>brightness<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cWhite<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><TT>(</TT>x<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>v<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>c<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>!</CODE>c<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw<CODE> </CODE>t<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE>draw<CODE> </CODE><TT>(</TT>List.map<CODE> </CODE><TT>(</TT><B>function</B><CODE> </CODE>P<CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<TT>)</TT><CODE> </CODE>lst<TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_choice : game -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* draw the list of pieces still available for each player *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_choice<CODE> </CODE><TT>(</TT>J<CODE> </CODE><TT>(</TT>ca<CODE>,</CODE>ma<CODE>,</CODE>r1<CODE>,</CODE>r2<TT>)</TT><TT>)</TT><CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlue<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE><TT>(</TT>choice_black_offset<CODE>-</CODE><CODE>3</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><CODE>6</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT>top_offset<CODE> </CODE><CODE>+</CODE><CODE> </CODE>bounds<TT>)</TT><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE><TT>(</TT>choice_red_offset<CODE>-</CODE><CODE>3</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><CODE>6</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT>top_offset<CODE> </CODE><CODE>+</CODE><CODE> </CODE>bounds<TT>)</TT><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_poss<CODE> </CODE><B>true</B><CODE> </CODE>r1<CODE> </CODE>choice_black_offset<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_poss<CODE> </CODE><B>false</B><CODE> </CODE>r2<CODE> </CODE>choice_red_offset<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* wait_click : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* wait for a mouse click *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>wait_click<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.wait_next_event<CODE> </CODE><CODE>[</CODE>Graphics<CODE>.</CODE>Button_down<CODE>]</CODE><BR><CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* item list -&gt; item  *)</CODE><BR><CODE> </CODE><CODE>(* return, for play, the piece chosen by the user *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>select_pion<CODE> </CODE>player<CODE> </CODE><CODE> </CODE>lst<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>ok<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><B>false</B><CODE> </CODE><B>and</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>choice<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>9</CODE><CODE>9</CODE><CODE> </CODE><B>and</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>pion<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><TT>(</TT>P<TT>(</TT><CODE>-</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE>not<CODE> </CODE><CODE>!</CODE>ok<CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>st<CODE> </CODE><CODE>=</CODE><CODE> </CODE>wait_click<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>size<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.length<CODE> </CODE>lst<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>st<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><B>and</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE>st<CODE>.</CODE>Graphics.mouse_y<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>choice<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><TT>(</TT>y<CODE>+</CODE><CODE>2</CODE><CODE>5</CODE><TT>)</TT><CODE>/</CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>choice<CODE> </CODE><CODE>&lt;=</CODE><CODE> </CODE>size<CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><TT>(</TT>player<CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE>x<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>6</CODE><CODE>5</CODE><CODE> </CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>||</CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><TT>(</TT>not<CODE> </CODE>player<TT>)</TT><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT>x<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE><CODE>5</CODE><CODE>3</CODE><CODE>5</CODE><TT>)</TT><TT>)</TT><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE>ok<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><B>true</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>ok<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><B>false</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE>!</CODE>ok<CODE> </CODE><B>then</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>pion<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><TT>(</TT>List.nth<CODE> </CODE><CODE> </CODE>lst<CODE> </CODE><CODE>!</CODE>choice<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cGreen<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_line_width<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_circle<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>choice_black_offset<CODE> </CODE><B>else</B><CODE> </CODE>choice_red_offset<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><TT>(</TT><CODE>!</CODE>choice<CODE>+</CODE><CODE>1</CODE><TT>)</TT><CODE>*</CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>brightness<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>ok<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><B>false</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>pion<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* choiceH : game -&gt; move  *)</CODE><BR><CODE> </CODE><CODE>(* return a move for the human player.</CODE><BR><CODE>   return the choice of the number, the case, and the piece *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>choice<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>game<CODE> </CODE><B>with</B><CODE> </CODE><TT>(</TT>J<TT>(</TT>ca<CODE>,</CODE>ma<CODE>,</CODE>r1<CODE>,</CODE>r2<TT>)</TT><TT>)</TT><CODE> </CODE>-&gt;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>choice<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><TT>(</TT>P<TT>(</TT><CODE>-</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><TT>(</TT><CODE>-</CODE><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>P<TT>(</TT><CODE>-</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>lcl<CODE> </CODE><CODE>=</CODE><CODE> </CODE>legal_moves<CODE> </CODE>player<CODE> </CODE>game<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>while</B><CODE> </CODE>not<CODE> </CODE><TT>(</TT>List.mem<CODE> </CODE><CODE>!</CODE>c<CODE> </CODE>lcl<TT>)</TT><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline();print_string<CODE> </CODE><CODE>"CHOICE"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>List.iter<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE><TT>(</TT>c<CODE>,</CODE>P<CODE> </CODE>p<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><CODE>"["</CODE>;<CODE> </CODE>print_int<CODE> </CODE>c;print_string<CODE> </CODE><CODE>" "</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_int<CODE> </CODE>p;print_string<CODE> </CODE><CODE>"]"</CODE><TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>legal_moves<CODE> </CODE>player<CODE> </CODE>game<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_choice<CODE> </CODE>game;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>choice<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE> </CODE>select_pion<CODE> </CODE>player<CODE> </CODE><CODE> </CODE><TT>(</TT><B>if</B><CODE> </CODE>player<CODE> </CODE><B>then</B><CODE> </CODE>r1<CODE> </CODE><B>else</B><CODE> </CODE>r2<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE>(*       print_string "choice "; print_piece !choice;*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>c<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>corresp2<CODE> </CODE><CODE> </CODE><TT>(</TT>conv<CODE> </CODE><TT>(</TT>wait_click()<TT>)</TT><TT>)</TT><CODE>,</CODE><CODE> </CODE><CODE>!</CODE>choice<TT>)</TT><BR><CODE> </CODE><CODE>(*       let (x,y) = !c in </CODE><BR><CODE>   (print_string "...";print_int x; print_string " "; print_piece y; </CODE><BR><CODE>   print_string " -&gt; "; </CODE><BR><CODE>   print_string "END_CHOICE";print_newline())</CODE><BR><CODE>*)</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE>c<CODE> </CODE><CODE>(* case, piece *)</CODE><BR><CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* home : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* place a message about the game *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>home<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.open_graph<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>" "</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE><TT>(</TT>width<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><TT>)</TT><TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"x"</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"+50+50"</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>/</CODE><CODE> </CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>width<CODE> </CODE><CODE>/</CODE><CODE> </CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlue<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE><CODE>"Stonehenge"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlack<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE><CODE>"Mixte Projets Ma�trise &amp; DESS GLA"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>wait_click<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.clear_graph<CODE> </CODE>()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* exit : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* close everything ! *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>exit<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.close_graph<CODE> </CODE>()<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_button : int -&gt; int -&gt; int -&gt; int -&gt; string -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* draw a button with a message *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_button<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>w<CODE> </CODE>h<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_line_width<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlack<CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE>x<CODE> </CODE><TT>(</TT>y<CODE>+</CODE>h<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE><TT>(</TT>x<CODE>+</CODE>w<TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE>+</CODE>h<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE><TT>(</TT>x<CODE>+</CODE>w<TT>)</TT><CODE> </CODE>y<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.lineto<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><TT>(</TT>x<CODE>+</CODE>bounds<TT>)</TT><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT>top_offset<CODE>/</CODE><CODE>2</CODE><TT>)</TT><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE>s<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* draw_message : string -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* position a message *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>draw_message<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>cBlack;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.moveto<CODE> </CODE><CODE>3</CODE><CODE> </CODE><TT>(</TT>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><TT>(</TT>top_offset<CODE>/</CODE><CODE>2</CODE><TT>)</TT><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_string<CODE> </CODE>s<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* erase_message : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* as the name indicates *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>erase_message<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.set_color<CODE> </CODE>Graphics.white;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.fill_rect<CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>height<CODE>-</CODE>top_offset<CODE>+</CODE>bounds<TT>)</TT><CODE> </CODE>width<CODE> </CODE>top_offset<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* question : string -&gt; bool  *)</CODE><BR><CODE> </CODE><CODE>(* pose the user a question, and wait for a yes/no response *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>question<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>xb1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>width<CODE>/</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE><B>and</B><CODE> </CODE>xb2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>width<CODE>/</CODE><CODE>2</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>3</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>and</B><CODE> </CODE>wb<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>5</CODE><CODE> </CODE><B>and</B><CODE> </CODE>hb<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>6</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>and</B><CODE> </CODE>yb<CODE> </CODE><CODE>=</CODE><CODE> </CODE>height<CODE> </CODE><CODE>-</CODE><CODE> </CODE><CODE>2</CODE><CODE>0</CODE><CODE> </CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>attente<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>wait_click<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_y<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><TT>(</TT>yb<CODE>+</CODE>hb<TT>)</TT><TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_y<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>yb<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>xb1<TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><TT>(</TT>xb1<CODE>+</CODE>wb<TT>)</TT><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>true</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&gt;</CODE><CODE> </CODE>xb2<TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE><TT>(</TT>e<CODE>.</CODE>Graphics.mouse_x<CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><TT>(</TT>xb2<CODE>+</CODE>wb<TT>)</TT><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>attente()<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>attente<CODE> </CODE>()<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_message<CODE> </CODE>s;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_button<CODE> </CODE>xb1<CODE> </CODE>yb<CODE> </CODE>wb<CODE> </CODE>hb<CODE> </CODE><CODE>"yes"</CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_button<CODE> </CODE>xb2<CODE> </CODE>yb<CODE> </CODE>wb<CODE> </CODE>hb<CODE> </CODE><CODE>"no"</CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>attente()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* q_begin : unit -&gt; bool *)</CODE><BR><CODE> </CODE><CODE>(* Ask if the player wishes to be the first player or not *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>q_begin<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Would you like to play first ?"</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>erase_message();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>b<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* q_continue : unit -&gt; bool *)</CODE><BR><CODE> </CODE><CODE>(* Ask if the user wishes to play the game again *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>q_continue<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Play again ?"</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>erase_message();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>b<BR><CODE> </CODE><CODE>(* won : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* a message indicating the machine has won *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>won<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>draw_message<CODE> </CODE><CODE>"I won :-)"</CODE>;<CODE> </CODE>wait_click();<CODE> </CODE>erase_message()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* lost : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* a message indicating the machine has lost *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>lost<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>draw_message<CODE> </CODE><CODE>"You won :-("</CODE>;<CODE> </CODE>wait_click();<CODE> </CODE>erase_message()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* nil : unit -&gt; unit  *)</CODE><BR><CODE> </CODE><CODE>(* a message indicating stalemate *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>nil<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>draw_message<CODE> </CODE><CODE>"Stalemate"</CODE>;<CODE> </CODE>wait_click();<CODE> </CODE>erase_message()<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* init : unit -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* draw the initial game board *)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>init<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>let</B><CODE> </CODE>game<CODE> </CODE><CODE>=</CODE><CODE> </CODE>game_start<CODE> </CODE>()<CODE> </CODE><B>in</B><BR><CODE> </CODE>draw_table<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE>draw_choice<CODE> </CODE>game<CODE> </CODE><BR><CODE> </CODE><BR><CODE> </CODE><CODE>(* drawH : move -&gt; game -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* draw a piece for the human player *)</CODE><BR><CODE> </CODE><CODE>(* let drawH cp j =  draw_piece cp cBlack ;</CODE><BR><CODE>   draw_lines_won j </CODE><BR><CODE>*)</CODE><BR><CODE> </CODE><CODE>(* drawM : move -&gt; game -&gt; unit *)</CODE><BR><CODE> </CODE><CODE>(* draw a piece for the machine player *)</CODE><BR><CODE> </CODE><CODE>(* let drawM cp j =  draw_piece cp cRed ;</CODE><BR><CODE>   draw_lines_won j </CODE><BR><CODE>*)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>print_placement<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>m<CODE> </CODE><B>with</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>None<CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><CODE>"None "</CODE><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>M<CODE> </CODE>j<CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE> </CODE><TT>(</TT><CODE>"Pl "</CODE><CODE>^</CODE><TT>(</TT><B>if</B><CODE> </CODE>j<CODE> </CODE><B>then</B><CODE> </CODE><CODE>"1 "</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>"2 "</CODE><TT>)</TT><TT>)</TT><BR><CODE> </CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>position<CODE> </CODE>player<CODE> </CODE>move<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>J<TT>(</TT>ca1<CODE>,</CODE>m1<CODE>,</CODE>r11<CODE>,</CODE>r12<TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>J<TT>(</TT>ca2<CODE>,</CODE>m2<CODE>,</CODE>r21<CODE>,</CODE>r22<TT>)</TT><CODE> </CODE><B>as</B><CODE> </CODE>new_game<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_piece<CODE> </CODE>player<CODE> </CODE>move;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>draw_choice<CODE> </CODE>new_game;<BR><CODE> </CODE><CODE>(*  print_string "_______OLD___________________\n";</CODE><BR><CODE>   Array.iter print_placement m1; print_newline();</CODE><BR><CODE>   List.iter print_piece r11; print_newline();</CODE><BR><CODE>   List.iter print_piece r12; print_newline();</CODE><BR><CODE>   print_string "_______NEW___________________\n";</CODE><BR><CODE>   Array.iter print_placement m2; print_newline();</CODE><BR><CODE>   List.iter print_piece r21; print_newline();</CODE><BR><CODE>   List.iter print_piece r22; print_newline();</CODE><BR><CODE>*)</CODE><CODE> </CODE><CODE> </CODE>draw_lines_won<CODE> </CODE>m1<CODE> </CODE>m2<BR><CODE> </CODE><BR><CODE> </CODE><CODE>(*</CODE><BR><CODE>   if player then draw_piece move cBlack </CODE><BR><CODE>   else  draw_piece move cRed</CODE><BR><CODE>*)</CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>q_player<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>question<CODE> </CODE><CODE>"Is there a machine playing?"</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>erase_message<CODE> </CODE>();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>b<BR><CODE> </CODE><B>end</B>;;<BR><CODE>Characters 11114-11127:</CODE><BR><CODE>Warning: this expression should have type unit.</CODE><BR><CODE>Characters 13197-13209:</CODE><BR><CODE>Warning: this expression should have type unit.</CODE><BR><CODE>Characters 13345-13357:</CODE><BR><CODE>Warning: this expression should have type unit.</CODE><BR><CODE>Characters 13478-13490:</CODE><BR><CODE>Warning: this expression should have type unit.</CODE><BR><CODE>module Stone_graph :</CODE><BR><CODE>  sig</CODE><BR><CODE>    type piece = Stone_rep.piece</CODE><BR><CODE>    and placement = Stone_rep.placement</CODE><BR><CODE>    and case = Stone_rep.case</CODE><BR><CODE>    and game = Stone_rep.game</CODE><BR><CODE>    and move = Stone_rep.move</CODE><BR><CODE>    val brightness : int</CODE><BR><CODE>    val cBlack : Graphics.color</CODE><BR><CODE>    val cRed : Graphics.color</CODE><BR><CODE>    val cYellow : Graphics.color</CODE><BR><CODE>    val cGreen : Graphics.color</CODE><BR><CODE>    val cWhite : Graphics.color</CODE><BR><CODE>    val cGray : Graphics.color</CODE><BR><CODE>    val cBlue : Graphics.color</CODE><BR><CODE>    val width : int</CODE><BR><CODE>    val height : int</CODE><BR><CODE>    val top_offset : int</CODE><BR><CODE>    val bounds : int</CODE><BR><CODE>    val virtual_table_xoffset : int</CODE><BR><CODE>    val choice_black_offset : int</CODE><BR><CODE>    val choice_red_offset : int</CODE><BR><CODE>    val virtual_case_size : int</CODE><BR><CODE>    val corresp : int -&gt; int * int</CODE><BR><CODE>    val corresp2 : int * int -&gt; int</CODE><BR><CODE>    val col : int</CODE><BR><CODE>    val lig : int</CODE><BR><CODE>    val draw_background : unit -&gt; unit</CODE><BR><CODE>    val draw_places : unit -&gt; unit</CODE><BR><CODE>    val draw_force_lines : unit -&gt; unit</CODE><BR><CODE>    val draw_final_places : unit -&gt; unit</CODE><BR><CODE>    val draw_table : unit -&gt; unit</CODE><BR><CODE>    val draw_piece : bool -&gt; int * Stone_rep.piece -&gt; unit</CODE><BR><CODE>    val conv : Graphics.status -&gt; int * int</CODE><BR><CODE>    val line_number_to_aff : int -&gt; int * int</CODE><BR><CODE>    val drawb : Stone_rep.placement -&gt; int -&gt; unit</CODE><BR><CODE>    val draw_lines_won :</CODE><BR><CODE>      Stone_rep.placement array -&gt; Stone_rep.placement array -&gt; unit</CODE><BR><CODE>    val draw_poss : bool -&gt; Stone_rep.piece list -&gt; int -&gt; unit</CODE><BR><CODE>    val draw_choice : Stone_rep.game -&gt; unit</CODE><BR><CODE>    val wait_click : unit -&gt; Graphics.status</CODE><BR><CODE>    val select_pion : bool -&gt; Stone_rep.piece list -&gt; Stone_rep.piece</CODE><BR><CODE>    val choice : bool -&gt; Stone_rep.game -&gt; int * Stone_rep.piece</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val draw_button : int -&gt; int -&gt; int -&gt; int -&gt; string -&gt; unit</CODE><BR><CODE>    val draw_message : string -&gt; unit</CODE><BR><CODE>    val erase_message : unit -&gt; unit</CODE><BR><CODE>    val question : string -&gt; bool</CODE><BR><CODE>    val q_begin : unit -&gt; bool</CODE><BR><CODE>    val q_continue : unit -&gt; bool</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; unit</CODE><BR><CODE>    val print_placement : Stone_rep.placement -&gt; unit</CODE><BR><CODE>    val position :</CODE><BR><CODE>      bool -&gt;</CODE><BR><CODE>      int * Stone_rep.piece -&gt; Stone_rep.game -&gt; Stone_rep.game -&gt; unit</CODE><BR><CODE>    val q_player : unit -&gt; bool</CODE><BR><CODE>  end</CODE><BR>

</PRE>

<BR>
<BR>

<H5> Assembly.</H5>We thus write module <TT>Stone_graph</TT> which describes a graphical
interface compatible with signature <TT>DISPLAY</TT>. We construct 
<TT>Stone_skeletonG</TT> similar to 
<TT>C4_skeletonG</TT>, passing in the arguments appropriate for the
Stonehenge game, applying the parametric module <TT>FSkeleton</TT>.<BR>
<BR>


<PRE><BR># <B>module</B><CODE> </CODE>Stone_skeletonG<CODE> </CODE><CODE>=</CODE><CODE> </CODE>FSkeleton<CODE> </CODE><TT>(</TT>Stone_rep<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Stone_graph<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Stone_eval<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>FAlphabeta<CODE> </CODE><TT>(</TT>Stone_rep<TT>)</TT><CODE> </CODE><TT>(</TT>Stone_eval<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>module Stone_skeletonG :</CODE><BR><CODE>  sig</CODE><BR><CODE>    val depth : int ref</CODE><BR><CODE>    exception Won</CODE><BR><CODE>    exception Lost</CODE><BR><CODE>    exception Nil</CODE><BR><CODE>    val won : unit -&gt; unit</CODE><BR><CODE>    val lost : unit -&gt; unit</CODE><BR><CODE>    val nil : unit -&gt; unit</CODE><BR><CODE>    val again : unit -&gt; bool</CODE><BR><CODE>    val play_game : Stone_graph.game ref</CODE><BR><CODE>    val exit : unit -&gt; unit</CODE><BR><CODE>    val home : unit -&gt; unit</CODE><BR><CODE>    val playH : bool -&gt; unit -&gt; unit</CODE><BR><CODE>    val playM : bool -&gt; unit -&gt; unit</CODE><BR><CODE>    val init : unit -&gt; (unit -&gt; unit) * (unit -&gt; unit)</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
We may thus construct the principal module <TT>Stone_mainG</TT>.


<PRE><BR># <B>module</B><CODE> </CODE>Stone_mainG<CODE> </CODE><CODE>=</CODE><CODE> </CODE>FMain<TT>(</TT>Stone_skeletonG<TT>)</TT><CODE> </CODE>;;<BR><CODE>module Stone_mainG :</CODE><BR><CODE>  sig</CODE><BR><CODE>    val play_game : (unit -&gt; 'a) * (unit -&gt; 'b) -&gt; unit</CODE><BR><CODE>    val main : unit -&gt; unit</CODE><BR><CODE>  end</CODE><BR>

</PRE>
<BR>
<BR>
Launching <TT>Stone_mainG.main ()</TT> opens the window shown in
figure <A HREF="book-ora160.html#fig-stonehenge1">17.6</A>. After displaying a dialogue to show
who is playing, the game begins. A human player will select a piece
and place it.<BR>
<BR>
<A NAME="toc234"></A>
<H3> To Learn More</H3>This organization of these applications involves using several
parametric modules that permit direct reuse of 
<TT>FAlphabeta</TT> and <TT>FSkeleton</TT> for the two games we have
written. With Stonehenge, some of the functions from 
<TT>Stone_rep</TT>, needed for <TT>play</TT>, which do not
appear in <TT>REPRESENTATION</TT>, are used by the
evaluation function. That is why the module <TT>Stone_rep</TT> was
not closed immediately by <TT>REPRESENTATION</TT>. This
partitioning of modules for the specific aspects of games allows
incremental development without making the game schema dependencies
(presented in figure <A HREF="book-ora160.html#fig-orgjeux">17.4</A>) fragile.<BR>
<BR>
A first enhancement involves games where given a position and a move,
it is easy to determine the preceding position. In such cases, it may
be more efficient to not bother making a copy of the game for function
<TT>play</TT>, but rather to conserve a history of moves played to
allow backtracking. This is the case for Connect&nbsp;4, but not for Stonehenge.
<BR>
<BR>
A second improvement is to capitalize on a player's response time
by evaluating future positions while the other player is
selecting his next move. For this, one may use threads (see
chapter <A HREF="index.html#chap-PC">19</A>), which allow concurrent calculation. 
If the player's response is one that has already been 
explored, the gain in time will be immediate, if not we must start
again from the new position.<BR>
<BR>
A third enhancement is to build and exploit dictionaries of opening
moves. We have been able to do so with Stonehenge, but it is also
useful for many other games where the set of legal moves to explore is
particularly large and complex at the start of the game. There is
much to be gained from estimating and precalculating some ``best''
moves from the starting positions and retaining them in some sort of
database. One may add a bit of ``spice'' (and perhaps
unpredictability) to the games by introducing an element of
chance, by picking randomly from a set of moves with similar or
identical values.<BR>
<BR>
A fourth view is to not limit the search depth to a fixed depth value,
but rather to limit the search by a calculation time period that is
not to be exceeded. In this manner, the program will be able to
efficiently search to deeper depths when the number of remaining moves
becomes limited. This modification requires slight modification to 
<TT>minmax</TT> in order to be able to re-examine a tree to increase its
depth.<BR>
<BR>
A game-dependent heuristic, parameterized by <TT>minmax</TT>, may be
to choose which branches in the search should be pursued and
which may be quickly abandoned.<BR>
<BR>
There are also many other games that require little more than to be
implemented or reimplemented. We might cite many classic games:
Checkers, Othello, Abalone, ..., but also many lesser-known games
that are, nevertheless, readily playable by computer. You may find on
the web various student projects including Checkers or the game Nuba.<BR>
<BR>


<H3> Link </H3> <HR>

<A HREF="http://www.gamecabinet.com/rules/Nuba.html">http://www.gamecabinet.com/rules/Nuba.html</A>


<HR>

 <BR>
<BR>
Games with stochastic qualities, such as card games and dice games,
necessitate a modification of the minimax-<FONT FACE=symbol>a</FONT><FONT FACE=symbol>b</FONT> algorithm in
order to take account of the probabilities of the selections.<BR>
<BR>
We will return to the interfaces of games in chapter
<A HREF="index.html#chap-PART4-Applications">21</A> in constructing web-based interfaces,
providing without further cost the ability to return to the last move.
This also allows further benefits from the modular organization that
allows modifying no more than just an element, here the game state and
interactions, to extend the functionality to support two player games.<BR>
<BR>
<BR>
<BR>
<HR>
<A HREF="book-ora159.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora161.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
